From 704379757cd4db06aa027c0e96b911efd3f3e285 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Sat, 31 Jan 2015 20:35:44 -0500 Subject: [PATCH 01/12] bump(github.com/GoogleCloudPlatform/kubernetes):e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9 --- Godeps/Godeps.json | 213 +- .../compute/v1/v1/compute-api.json | 9526 --------- .../compute/v1/v1/compute-gen.go | 16952 ---------------- .../v1beta1/v1beta1/container-api.json | 579 - .../v1beta1/v1beta1/container-gen.go | 1007 - .../kubernetes/pkg/api/errors/errors.go | 20 +- .../kubernetes/pkg/api/errors/validation.go | 11 +- .../pkg/api/errors/validation_test.go | 7 +- .../kubernetes/pkg/api/helpers.go | 13 + .../kubernetes/pkg/api/helpers_test.go | 18 + .../kubernetes/pkg/api/latest/latest_test.go | 115 +- .../kubernetes/pkg/api/register.go | 10 + .../kubernetes/pkg/api/serialization_test.go | 139 +- .../kubernetes/pkg/api/testing/fuzzer.go | 162 + .../kubernetes/pkg/api/types.go | 159 +- .../kubernetes/pkg/api/v1beta1/conversion.go | 188 +- .../kubernetes/pkg/api/v1beta1/register.go | 10 + .../kubernetes/pkg/api/v1beta1/types.go | 141 +- .../kubernetes/pkg/api/v1beta2/conversion.go | 188 +- .../kubernetes/pkg/api/v1beta2/register.go | 10 + .../kubernetes/pkg/api/v1beta2/types.go | 140 +- .../kubernetes/pkg/api/v1beta3/register.go | 10 + .../kubernetes/pkg/api/v1beta3/types.go | 155 +- .../pkg/api/validation/schema_test.go | 95 +- .../pkg/api/validation/validation.go | 285 +- .../pkg/api/validation/validation_test.go | 472 +- .../kubernetes/pkg/apiserver/apiserver.go | 26 +- .../pkg/apiserver/apiserver_test.go | 202 +- .../kubernetes/pkg/apiserver/handlers.go | 9 +- .../kubernetes/pkg/apiserver/operation.go | 40 +- .../pkg/apiserver/operation_test.go | 225 - .../kubernetes/pkg/apiserver/resthandler.go | 20 +- .../kubernetes/pkg/apiserver/validator.go | 23 +- .../pkg/apiserver/validator_test.go | 10 +- .../authorizer/abac/example_policy_file.jsonl | 4 +- .../kubernetes/pkg/client/cache/fifo.go | 68 +- .../kubernetes/pkg/client/cache/fifo_test.go | 93 +- .../kubernetes/pkg/client/cache/listers.go | 13 +- .../pkg/client/cache/listers_test.go | 8 +- .../kubernetes/pkg/client/cache/poller.go | 15 +- .../pkg/client/cache/poller_test.go | 33 +- .../kubernetes/pkg/client/cache/reflector.go | 21 +- .../pkg/client/cache/reflector_test.go | 35 +- .../kubernetes/pkg/client/cache/store.go | 101 +- .../kubernetes/pkg/client/cache/store_test.go | 71 +- .../pkg/client/cache/undelta_store.go | 43 +- .../pkg/client/cache/undelta_store_test.go | 53 +- .../kubernetes/pkg/client/client.go | 15 + .../kubernetes/pkg/client/client_test.go | 21 + .../kubernetes/pkg/client/clientcmd/loader.go | 2 + .../pkg/client/clientcmd/loader_test.go | 104 + .../pkg/client/clientcmd/overrides.go | 11 +- .../kubernetes/pkg/client/fake.go | 33 +- .../pkg/client/fake_limit_ranges.go | 54 + .../kubernetes/pkg/client/fake_minions.go | 5 + .../client/fake_replication_controllers.go | 2 +- .../pkg/client/fake_resource_quota_usages.go | 33 + .../pkg/client/fake_resource_quotas.go | 54 + .../kubernetes/pkg/client/kubelet.go | 16 +- .../kubernetes/pkg/client/kubelet_test.go | 46 +- .../kubernetes/pkg/client/limit_ranges.go | 94 + .../pkg/client/limit_ranges_test.go | 194 + .../kubernetes/pkg/client/minions.go | 20 +- .../kubernetes/pkg/client/request.go | 96 +- .../kubernetes/pkg/client/request_test.go | 121 +- .../pkg/client/resource_quota_usages.go | 57 + .../pkg/client/resource_quota_usages_test.go | 93 + .../kubernetes/pkg/client/resource_quotas.go | 94 + .../pkg/client/resource_quotas_test.go | 177 + .../kubernetes/pkg/client/restclient.go | 38 +- .../kubernetes/pkg/client/restclient_test.go | 21 +- .../controller/nodecontroller.go | 227 +- .../controller/nodecontroller_test.go | 479 +- .../kubernetes/pkg/cloudprovider/gce/gce.go | 7 +- .../pkg/controller/replication_controller.go | 19 +- .../controller/replication_controller_test.go | 6 + .../pkg/credentialprovider/config.go | 61 +- .../pkg/credentialprovider/keyring.go | 17 +- .../pkg/credentialprovider/provider.go | 2 +- .../kubernetes/pkg/health/exec.go | 59 - .../kubernetes/pkg/health/exec_test.go | 85 - .../kubernetes/pkg/health/health.go | 115 - .../kubernetes/pkg/health/health_test.go | 142 - .../kubernetes/pkg/health/http.go | 119 - .../kubernetes/pkg/health/tcp.go | 88 - .../kubernetes/pkg/health/tcp_test.go | 115 - .../pkg/kubecfg/resource_printer_test.go | 32 +- .../kubernetes/pkg/kubectl/cmd/cmd.go | 6 +- .../kubernetes/pkg/kubectl/cmd/cmd_test.go | 25 + .../pkg/kubectl/cmd/config/config_test.go | 16 +- .../pkg/kubectl/cmd/config/create_authinfo.go | 49 +- .../pkg/kubectl/cmd/config/create_cluster.go | 51 +- .../pkg/kubectl/cmd/config/create_context.go | 42 +- .../kubernetes/pkg/kubectl/cmd/create_test.go | 2 +- .../kubernetes/pkg/kubectl/cmd/delete_test.go | 2 +- .../kubernetes/pkg/kubectl/cmd/proxy.go | 4 +- .../kubernetes/pkg/kubectl/describe.go | 94 +- .../kubernetes/pkg/kubectl/kubectl.go | 12 +- .../kubernetes/pkg/kubectl/proxy_server.go | 9 +- .../pkg/kubectl/resource_printer.go | 42 + .../pkg/kubectl/resource_printer_test.go | 32 +- .../pkg/kubectl/sorted_event_list_test.go | 5 +- .../pkg/kubectl/sorted_resource_name_list.go | 35 + .../pkg/kubelet/config/apiserver.go | 2 +- .../pkg/kubelet/config/apiserver_test.go | 41 + .../pkg/kubelet/config/file_test.go | 10 +- .../pkg/kubelet/dockertools/docker.go | 25 +- .../pkg/kubelet/dockertools/docker_test.go | 44 + .../kubernetes/pkg/kubelet/handlers.go | 3 +- .../kubernetes/pkg/kubelet/kubelet.go | 117 +- .../kubernetes/pkg/kubelet/kubelet_test.go | 129 +- .../kubernetes/pkg/kubelet/leaky/leaky.go | 25 + .../kubernetes/pkg/kubelet/probe.go | 125 + .../http_test.go => kubelet/probe_test.go} | 121 +- .../kubernetes/pkg/kubelet/util.go | 11 - .../pkg/kubelet/volume/gce_pd/gce_pd.go | 17 +- ...mount_util_linux.go => mount_util_unix.go} | 0 .../volume/gce_pd/mount_util_unsupported.go | 2 +- .../kubernetes/pkg/master/master.go | 56 +- .../kubernetes/pkg/master/pod_cache.go | 107 +- .../kubernetes/pkg/master/pod_cache_test.go | 175 +- .../kubernetes/pkg/master/publish.go | 2 +- .../kubernetes/pkg/master/rest_to_nodes.go | 11 +- .../kubernetes/pkg/master/server/plugins.go | 36 + .../kubernetes/pkg/master/server/server.go | 344 + .../kubernetes/pkg/probe/doc.go | 18 + .../kubernetes/pkg/probe/exec/exec.go | 46 + .../kubernetes/pkg/probe/exec/exec_test.go | 69 + .../kubernetes/pkg/probe/http/http.go | 73 + .../kubernetes/pkg/probe/http/http_test.go | 85 + .../kubernetes/pkg/probe/probe.go | 37 + .../kubernetes/pkg/probe/tcp/tcp.go | 52 + .../kubernetes/pkg/probe/tcp/tcp_test.go | 73 + .../kubernetes/pkg/proxy/loadbalancer.go | 3 +- .../kubernetes/pkg/proxy/roundrobin.go | 5 +- .../kubernetes/pkg/proxy/roundrobin_test.go | 205 +- .../pkg/registry/controller/rest.go | 11 +- .../pkg/registry/controller/rest_test.go | 17 +- .../kubernetes/pkg/registry/etcd/etcd.go | 12 +- .../kubernetes/pkg/registry/limitrange/doc.go | 19 + .../pkg/registry/limitrange/registry.go | 48 + .../pkg/registry/limitrange/registry_test.go | 121 + .../pkg/registry/limitrange/rest.go | 159 + .../limitrange/rest_test.go} | 3 +- .../pkg/registry/minion/healthy_registry.go | 125 - .../registry/minion/healthy_registry_test.go | 114 - .../kubernetes/pkg/registry/minion/rest.go | 10 +- .../pkg/registry/minion/rest_test.go | 68 +- .../kubernetes/pkg/registry/pod/rest.go | 7 + .../kubernetes/pkg/registry/pod/rest_test.go | 35 + .../pkg/registry/resourcequota/doc.go | 19 + .../pkg/registry/resourcequota/registry.go | 75 + .../registry/resourcequota/registry_test.go | 116 + .../pkg/registry/resourcequota/rest.go | 162 + .../pkg/registry/resourcequota/rest_test.go | 17 + .../pkg/registry/resourcequotausage/doc.go | 19 + .../registry/resourcequotausage/registry.go | 28 + .../pkg/registry/resourcequotausage/rest.go | 56 + .../registry/resourcequotausage/rest_test.go | 17 + .../kubernetes/pkg/registry/service/rest.go | 25 +- .../pkg/registry/service/rest_test.go | 16 +- .../kubernetes/pkg/runtime/types.go | 2 - .../kubernetes/pkg/tools/etcd_tools.go | 2 +- .../kubernetes/pkg/tools/etcd_tools_test.go | 36 +- .../kubernetes/pkg/tools/fake_etcd_client.go | 15 + .../kubernetes/pkg/util/bool_flag.go | 64 + .../kubernetes/pkg/util/pflag_import.go | 4 +- .../kubernetes/pkg/util/slice/slice.go | 49 + .../kubernetes/pkg/util/slice/slice_test.go | 70 + .../kubernetes/pkg/util/string_flag.go | 52 + .../kubernetes/pkg/util/template.go | 48 + .../kubernetes/pkg/util/template_test.go | 61 + .../kubernetes/pkg/util/util.go | 19 + .../kubernetes/pkg/util/util_test.go | 34 + .../plugin/pkg/scheduler/factory/factory.go | 19 +- .../pkg/scheduler/factory/factory_test.go | 8 +- .../src/github.com/coreos/etcd/mod/mod.go | 8 +- .../github.com/getsentry/raven-go/client.go | 17 - 178 files changed, 7554 insertions(+), 31460 deletions(-) delete mode 100644 Godeps/_workspace/src/code.google.com/p/google-api-go-client/compute/v1/v1/compute-api.json delete mode 100644 Godeps/_workspace/src/code.google.com/p/google-api-go-client/compute/v1/v1/compute-gen.go delete mode 100644 Godeps/_workspace/src/code.google.com/p/google-api-go-client/container/v1beta1/v1beta1/container-api.json delete mode 100644 Godeps/_workspace/src/code.google.com/p/google-api-go-client/container/v1beta1/v1beta1/container-gen.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/testing/fuzzer.go delete mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/operation_test.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake_limit_ranges.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake_resource_quota_usages.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake_resource_quotas.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/limit_ranges.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/limit_ranges_test.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/resource_quota_usages.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/resource_quota_usages_test.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/resource_quotas.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/resource_quotas_test.go delete mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/exec.go delete mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/exec_test.go delete mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/health.go delete mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/health_test.go delete mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/http.go delete mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/tcp.go delete mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/tcp_test.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/sorted_resource_name_list.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/leaky/leaky.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/probe.go rename Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/{health/http_test.go => kubelet/probe_test.go} (57%) rename Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/volume/gce_pd/{mount_util_linux.go => mount_util_unix.go} (100%) create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/server/plugins.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/server/server.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/doc.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/exec/exec.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/exec/exec_test.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/http/http.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/http/http_test.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/probe.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/tcp/tcp.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/tcp/tcp_test.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/limitrange/doc.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/limitrange/registry.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/limitrange/registry_test.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/limitrange/rest.go rename Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/{health/doc.go => registry/limitrange/rest_test.go} (83%) delete mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion/healthy_registry.go delete mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion/healthy_registry_test.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/doc.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/registry.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/registry_test.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/rest.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/rest_test.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequotausage/doc.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequotausage/registry.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequotausage/rest.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequotausage/rest_test.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/bool_flag.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/slice/slice.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/slice/slice_test.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/string_flag.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/template.go create mode 100644 Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/template_test.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 2ce4ffa6cd11..75bcc30a31fc 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -17,243 +17,258 @@ }, { "ImportPath": "code.google.com/p/google-api-go-client/compute/v1", - "Comment": "release-107", - "Rev": "6ddfebb10ece847f1ae09c701834f1b15abbd8b2" + "Comment": "release-105", + "Rev": "98c78185197025f935947caac56a7b6d022f89d2" }, { "ImportPath": "code.google.com/p/google-api-go-client/container/v1beta1", - "Comment": "release-107", - "Rev": "6ddfebb10ece847f1ae09c701834f1b15abbd8b2" + "Comment": "release-105", + "Rev": "98c78185197025f935947caac56a7b6d022f89d2" }, { "ImportPath": "code.google.com/p/google-api-go-client/googleapi", - "Comment": "release-107", - "Rev": "6ddfebb10ece847f1ae09c701834f1b15abbd8b2" + "Comment": "release-105", + "Rev": "98c78185197025f935947caac56a7b6d022f89d2" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/admission", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/api", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authenticator", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authorizer", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/auth/handlers", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/auth/user", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/capabilities", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/client", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/clientauth", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/constraint", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/controller", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/conversion", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" - }, - { - "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/health", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/healthz", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/httplog", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/kubecfg", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/labels", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/master", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" + }, + { + "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/probe", + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/proxy", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/binding", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/controller", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/endpoint", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/etcd", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/event", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" + }, + { + "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/limitrange", + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" + }, + { + "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota", + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" + }, + { + "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequotausage", + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/scheduler", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/service", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/tools", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/types", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/ui", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/util", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/version", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/pkg/watch", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/admit", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/auth/authenticator/token/tokenfile", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler", - "Comment": "v0.9.0-117-ge0acd75", - "Rev": "e0acd75629ec29bde764bcde29367146ae8b389b" + "Comment": "v0.9.0-391-ge335e2d", + "Rev": "e335e2d3e26a9a58d3b189ccf41ceb3770d1bfa9" }, { "ImportPath": "github.com/RangelReale/osin", diff --git a/Godeps/_workspace/src/code.google.com/p/google-api-go-client/compute/v1/v1/compute-api.json b/Godeps/_workspace/src/code.google.com/p/google-api-go-client/compute/v1/v1/compute-api.json deleted file mode 100644 index 726a0ac363d3..000000000000 --- a/Godeps/_workspace/src/code.google.com/p/google-api-go-client/compute/v1/v1/compute-api.json +++ /dev/null @@ -1,9526 +0,0 @@ -{ - "kind": "discovery#restDescription", - "etag": "\"l66ggWbucbkBw9Lpos72oziyefE/qp3DHGvWPpREzEdWk7WwxnpgC9w\"", - "discoveryVersion": "v1", - "id": "compute:v1", - "name": "compute", - "version": "v1", - "revision": "20141014", - "title": "Compute Engine API", - "description": "API for the Google Compute Engine service.", - "ownerDomain": "google.com", - "ownerName": "Google", - "icons": { - "x16": "https://www.google.com/images/icons/product/compute_engine-16.png", - "x32": "https://www.google.com/images/icons/product/compute_engine-32.png" - }, - "documentationLink": "https://developers.google.com/compute/docs/reference/latest/", - "protocol": "rest", - "baseUrl": "https://www.googleapis.com/compute/v1/projects/", - "basePath": "/compute/v1/projects/", - "rootUrl": "https://www.googleapis.com/", - "servicePath": "compute/v1/projects/", - "batchPath": "batch", - "parameters": { - "alt": { - "type": "string", - "description": "Data format for the response.", - "default": "json", - "enum": [ - "json" - ], - "enumDescriptions": [ - "Responses with Content-Type of application/json" - ], - "location": "query" - }, - "fields": { - "type": "string", - "description": "Selector specifying which fields to include in a partial response.", - "location": "query" - }, - "key": { - "type": "string", - "description": "API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.", - "location": "query" - }, - "oauth_token": { - "type": "string", - "description": "OAuth 2.0 token for the current user.", - "location": "query" - }, - "prettyPrint": { - "type": "boolean", - "description": "Returns response with indentations and line breaks.", - "default": "true", - "location": "query" - }, - "quotaUser": { - "type": "string", - "description": "Available to use for quota purposes for server-side applications. Can be any arbitrary string assigned to a user, but should not exceed 40 characters. Overrides userIp if both are provided.", - "location": "query" - }, - "userIp": { - "type": "string", - "description": "IP address of the site where the request originates. Use this if you want to enforce per-user limits.", - "location": "query" - } - }, - "auth": { - "oauth2": { - "scopes": { - "https://www.googleapis.com/auth/compute": { - "description": "View and manage your Google Compute Engine resources" - }, - "https://www.googleapis.com/auth/compute.readonly": { - "description": "View your Google Compute Engine resources" - }, - "https://www.googleapis.com/auth/devstorage.full_control": { - "description": "Manage your data and permissions in Google Cloud Storage" - }, - "https://www.googleapis.com/auth/devstorage.read_only": { - "description": "View your data in Google Cloud Storage" - }, - "https://www.googleapis.com/auth/devstorage.read_write": { - "description": "Manage your data in Google Cloud Storage" - } - } - } - }, - "schemas": { - "AccessConfig": { - "id": "AccessConfig", - "type": "object", - "description": "An access configuration attached to an instance's network interface.", - "properties": { - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#accessConfig" - }, - "name": { - "type": "string", - "description": "Name of this access configuration." - }, - "natIP": { - "type": "string", - "description": "An external IP address associated with this instance. Specify an unused static IP address available to the project. If not specified, the external IP will be drawn from a shared ephemeral pool." - }, - "type": { - "type": "string", - "description": "Type of configuration. Must be set to \"ONE_TO_ONE_NAT\". This configures port-for-port NAT to the internet.", - "default": "ONE_TO_ONE_NAT", - "enum": [ - "ONE_TO_ONE_NAT" - ], - "enumDescriptions": [ - "" - ] - } - } - }, - "Address": { - "id": "Address", - "type": "object", - "description": "A reserved address resource.", - "properties": { - "address": { - "type": "string", - "description": "The IP address represented by this resource." - }, - "creationTimestamp": { - "type": "string", - "description": "Creation timestamp in RFC3339 text format (output only)." - }, - "description": { - "type": "string", - "description": "An optional textual description of the resource; provided by the client when the resource is created." - }, - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only).", - "format": "uint64" - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#address" - }, - "name": { - "type": "string", - "description": "Name of the resource; provided by the client when the resource is created. The name must be 1-63 characters long, and comply with RFC1035.", - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "annotations": { - "required": [ - "compute.addresses.insert" - ] - } - }, - "region": { - "type": "string", - "description": "URL of the region where the regional address resides (output only). This field is not applicable to global addresses." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - }, - "status": { - "type": "string", - "description": "The status of the address (output only).", - "enum": [ - "IN_USE", - "RESERVED" - ], - "enumDescriptions": [ - "", - "" - ] - }, - "users": { - "type": "array", - "description": "The resources that are using this address resource.", - "items": { - "type": "string" - } - } - } - }, - "AddressAggregatedList": { - "id": "AddressAggregatedList", - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "object", - "description": "A map of scoped address lists.", - "additionalProperties": { - "$ref": "AddressesScopedList", - "description": "Name of the scope containing this set of addresses." - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#addressAggregatedList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "AddressList": { - "id": "AddressList", - "type": "object", - "description": "Contains a list of address resources.", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "array", - "description": "The address resources.", - "items": { - "$ref": "Address" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#addressList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - } - } - }, - "AddressesScopedList": { - "id": "AddressesScopedList", - "type": "object", - "properties": { - "addresses": { - "type": "array", - "description": "List of addresses contained in this scope.", - "items": { - "$ref": "Address" - } - }, - "warning": { - "type": "object", - "description": "Informational warning which replaces the list of addresses when the list is empty.", - "properties": { - "code": { - "type": "string", - "description": "The warning type identifier for this warning.", - "enum": [ - "DEPRECATED_RESOURCE_USED", - "DISK_SIZE_LARGER_THAN_IMAGE_SIZE", - "INJECTED_KERNELS_DEPRECATED", - "NEXT_HOP_ADDRESS_NOT_ASSIGNED", - "NEXT_HOP_CANNOT_IP_FORWARD", - "NEXT_HOP_INSTANCE_NOT_FOUND", - "NEXT_HOP_INSTANCE_NOT_ON_NETWORK", - "NEXT_HOP_NOT_RUNNING", - "NO_RESULTS_ON_PAGE", - "REQUIRED_TOS_AGREEMENT", - "RESOURCE_NOT_DELETED", - "UNREACHABLE" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "data": { - "type": "array", - "description": "Metadata for this warning in 'key: value' format.", - "items": { - "type": "object", - "properties": { - "key": { - "type": "string", - "description": "A key for the warning data." - }, - "value": { - "type": "string", - "description": "A warning data value corresponding to the key." - } - } - } - }, - "message": { - "type": "string", - "description": "Optional human-readable details for this warning." - } - } - } - } - }, - "AttachedDisk": { - "id": "AttachedDisk", - "type": "object", - "description": "An instance-attached disk resource.", - "properties": { - "autoDelete": { - "type": "boolean", - "description": "Whether the disk will be auto-deleted when the instance is deleted (but not when the disk is detached from the instance)." - }, - "boot": { - "type": "boolean", - "description": "Indicates that this is a boot disk. VM will use the first partition of the disk for its root filesystem." - }, - "deviceName": { - "type": "string", - "description": "Persistent disk only; must be unique within the instance when specified. This represents a unique device name that is reflected into the /dev/ tree of a Linux operating system running within the instance. If not specified, a default will be chosen by the system." - }, - "index": { - "type": "integer", - "description": "A zero-based index to assign to this disk, where 0 is reserved for the boot disk. If not specified, the server will choose an appropriate value (output only).", - "format": "int32" - }, - "initializeParams": { - "$ref": "AttachedDiskInitializeParams", - "description": "Initialization parameters." - }, - "interface": { - "type": "string", - "enum": [ - "NVME", - "SCSI" - ], - "enumDescriptions": [ - "", - "" - ] - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#attachedDisk" - }, - "licenses": { - "type": "array", - "description": "Public visible licenses.", - "items": { - "type": "string" - } - }, - "mode": { - "type": "string", - "description": "The mode in which to attach this disk, either \"READ_WRITE\" or \"READ_ONLY\".", - "enum": [ - "READ_ONLY", - "READ_WRITE" - ], - "enumDescriptions": [ - "", - "" - ] - }, - "source": { - "type": "string", - "description": "Persistent disk only; the URL of the persistent disk resource." - }, - "type": { - "type": "string", - "description": "Type of the disk, either \"SCRATCH\" or \"PERSISTENT\". Note that persistent disks must be created before you can specify them here.", - "enum": [ - "PERSISTENT", - "SCRATCH" - ], - "enumDescriptions": [ - "", - "" - ], - "annotations": { - "required": [ - "compute.instances.insert" - ] - } - } - } - }, - "AttachedDiskInitializeParams": { - "id": "AttachedDiskInitializeParams", - "type": "object", - "description": "Initialization parameters for the new disk (input-only). Can only be specified on the boot disk or local SSDs. Mutually exclusive with 'source'.", - "properties": { - "diskName": { - "type": "string", - "description": "Name of the disk (when not provided defaults to the name of the instance)." - }, - "diskSizeGb": { - "type": "string", - "description": "Size of the disk in base-2 GB.", - "format": "int64" - }, - "diskType": { - "type": "string", - "description": "URL of the disk type resource describing which disk type to use to create the disk; provided by the client when the disk is created." - }, - "sourceImage": { - "type": "string", - "description": "The source image used to create this disk." - } - } - }, - "Backend": { - "id": "Backend", - "type": "object", - "description": "Message containing information of one individual backend.", - "properties": { - "balancingMode": { - "type": "string", - "description": "The balancing mode of this backend, default is UTILIZATION.", - "enum": [ - "RATE", - "UTILIZATION" - ], - "enumDescriptions": [ - "", - "" - ] - }, - "capacityScaler": { - "type": "number", - "description": "The multiplier (a value between 0 and 1e6) of the max capacity (CPU or RPS, depending on 'balancingMode') the group should serve up to. 0 means the group is totally drained. Default value is 1. Valid range is [0, 1e6].", - "format": "float" - }, - "description": { - "type": "string", - "description": "An optional textual description of the resource, which is provided by the client when the resource is created." - }, - "group": { - "type": "string", - "description": "URL of a zonal Cloud Resource View resource. This resource view defines the list of instances that serve traffic. Member virtual machine instances from each resource view must live in the same zone as the resource view itself. No two backends in a backend service are allowed to use same Resource View resource." - }, - "maxRate": { - "type": "integer", - "description": "The max RPS of the group. Can be used with either balancing mode, but required if RATE mode. For RATE mode, either maxRate or maxRatePerInstance must be set.", - "format": "int32" - }, - "maxRatePerInstance": { - "type": "number", - "description": "The max RPS that a single backed instance can handle. This is used to calculate the capacity of the group. Can be used in either balancing mode. For RATE mode, either maxRate or maxRatePerInstance must be set.", - "format": "float" - }, - "maxUtilization": { - "type": "number", - "description": "Used when 'balancingMode' is UTILIZATION. This ratio defines the CPU utilization target for the group. The default is 0.8. Valid range is [0, 1].", - "format": "float" - } - } - }, - "BackendService": { - "id": "BackendService", - "type": "object", - "description": "A BackendService resource. This resource defines a group of backend VMs together with their serving capacity.", - "properties": { - "backends": { - "type": "array", - "description": "The list of backends that serve this BackendService.", - "items": { - "$ref": "Backend" - } - }, - "creationTimestamp": { - "type": "string", - "description": "Creation timestamp in RFC3339 text format (output only)." - }, - "description": { - "type": "string", - "description": "An optional textual description of the resource; provided by the client when the resource is created." - }, - "fingerprint": { - "type": "string", - "description": "Fingerprint of this resource. A hash of the contents stored in this object. This field is used in optimistic locking. This field will be ignored when inserting a BackendService. An up-to-date fingerprint must be provided in order to update the BackendService.", - "format": "byte" - }, - "healthChecks": { - "type": "array", - "description": "The list of URLs to the HttpHealthCheck resource for health checking this BackendService. Currently at most one health check can be specified, and a health check is required.", - "items": { - "type": "string" - } - }, - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only).", - "format": "uint64" - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#backendService" - }, - "name": { - "type": "string", - "description": "Name of the resource; provided by the client when the resource is created. The name must be 1-63 characters long, and comply with RFC1035.", - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?" - }, - "port": { - "type": "integer", - "description": "Deprecated in favor of port_name. The TCP port to connect on the backend. The default value is 80.", - "format": "int32" - }, - "portName": { - "type": "string", - "description": "Name of backend port. The same name should appear in the resource views referenced by this service. Required." - }, - "protocol": { - "type": "string", - "enum": [ - "HTTP" - ], - "enumDescriptions": [ - "" - ] - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - }, - "timeoutSec": { - "type": "integer", - "description": "How many seconds to wait for the backend before considering it a failed request. Default is 30 seconds.", - "format": "int32" - } - } - }, - "BackendServiceGroupHealth": { - "id": "BackendServiceGroupHealth", - "type": "object", - "properties": { - "healthStatus": { - "type": "array", - "items": { - "$ref": "HealthStatus" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#backendServiceGroupHealth" - } - } - }, - "BackendServiceList": { - "id": "BackendServiceList", - "type": "object", - "description": "Contains a list of BackendService resources.", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "array", - "description": "The BackendService resources.", - "items": { - "$ref": "BackendService" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#backendServiceList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "DeprecationStatus": { - "id": "DeprecationStatus", - "type": "object", - "description": "Deprecation status for a public resource.", - "properties": { - "deleted": { - "type": "string", - "description": "An optional RFC3339 timestamp on or after which the deprecation state of this resource will be changed to DELETED." - }, - "deprecated": { - "type": "string", - "description": "An optional RFC3339 timestamp on or after which the deprecation state of this resource will be changed to DEPRECATED." - }, - "obsolete": { - "type": "string", - "description": "An optional RFC3339 timestamp on or after which the deprecation state of this resource will be changed to OBSOLETE." - }, - "replacement": { - "type": "string", - "description": "A URL of the suggested replacement for the deprecated resource. The deprecated resource and its replacement must be resources of the same kind." - }, - "state": { - "type": "string", - "description": "The deprecation state. Can be \"DEPRECATED\", \"OBSOLETE\", or \"DELETED\". Operations which create a new resource using a \"DEPRECATED\" resource will return successfully, but with a warning indicating the deprecated resource and recommending its replacement. New uses of \"OBSOLETE\" or \"DELETED\" resources will result in an error.", - "enum": [ - "DELETED", - "DEPRECATED", - "OBSOLETE" - ], - "enumDescriptions": [ - "", - "", - "" - ] - } - } - }, - "Disk": { - "id": "Disk", - "type": "object", - "description": "A persistent disk resource.", - "properties": { - "creationTimestamp": { - "type": "string", - "description": "Creation timestamp in RFC3339 text format (output only)." - }, - "description": { - "type": "string", - "description": "An optional textual description of the resource; provided by the client when the resource is created." - }, - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only).", - "format": "uint64" - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#disk" - }, - "licenses": { - "type": "array", - "description": "Public visible licenses.", - "items": { - "type": "string" - } - }, - "name": { - "type": "string", - "description": "Name of the resource; provided by the client when the resource is created. The name must be 1-63 characters long, and comply with RFC1035.", - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "annotations": { - "required": [ - "compute.disks.insert" - ] - } - }, - "options": { - "type": "string", - "description": "Internal use only." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - }, - "sizeGb": { - "type": "string", - "description": "Size of the persistent disk, specified in GB. This parameter is optional when creating a disk from a disk image or a snapshot, otherwise it is required.", - "format": "int64" - }, - "sourceImage": { - "type": "string", - "description": "The source image used to create this disk." - }, - "sourceImageId": { - "type": "string", - "description": "The 'id' value of the image used to create this disk. This value may be used to determine whether the disk was created from the current or a previous instance of a given image." - }, - "sourceSnapshot": { - "type": "string", - "description": "The source snapshot used to create this disk." - }, - "sourceSnapshotId": { - "type": "string", - "description": "The 'id' value of the snapshot used to create this disk. This value may be used to determine whether the disk was created from the current or a previous instance of a given disk snapshot." - }, - "status": { - "type": "string", - "description": "The status of disk creation (output only).", - "enum": [ - "CREATING", - "FAILED", - "READY", - "RESTORING" - ], - "enumDescriptions": [ - "", - "", - "", - "" - ] - }, - "type": { - "type": "string", - "description": "URL of the disk type resource describing which disk type to use to create the disk; provided by the client when the disk is created." - }, - "zone": { - "type": "string", - "description": "URL of the zone where the disk resides (output only)." - } - } - }, - "DiskAggregatedList": { - "id": "DiskAggregatedList", - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "object", - "description": "A map of scoped disk lists.", - "additionalProperties": { - "$ref": "DisksScopedList", - "description": "Name of the scope containing this set of disks." - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#diskAggregatedList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "DiskList": { - "id": "DiskList", - "type": "object", - "description": "Contains a list of persistent disk resources.", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "array", - "description": "The persistent disk resources.", - "items": { - "$ref": "Disk" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#diskList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "DiskType": { - "id": "DiskType", - "type": "object", - "description": "A disk type resource.", - "properties": { - "creationTimestamp": { - "type": "string", - "description": "Creation timestamp in RFC3339 text format (output only)." - }, - "defaultDiskSizeGb": { - "type": "string", - "description": "Server defined default disk size in gb (output only).", - "format": "int64" - }, - "deprecated": { - "$ref": "DeprecationStatus", - "description": "The deprecation status associated with this disk type." - }, - "description": { - "type": "string", - "description": "An optional textual description of the resource." - }, - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only).", - "format": "uint64" - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#diskType" - }, - "name": { - "type": "string", - "description": "Name of the resource.", - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?" - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - }, - "validDiskSize": { - "type": "string", - "description": "An optional textual descroption of the valid disk size, e.g., \"10GB-10TB\"." - }, - "zone": { - "type": "string", - "description": "Url of the zone where the disk type resides (output only)." - } - } - }, - "DiskTypeAggregatedList": { - "id": "DiskTypeAggregatedList", - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "object", - "description": "A map of scoped disk type lists.", - "additionalProperties": { - "$ref": "DiskTypesScopedList", - "description": "Name of the scope containing this set of disk types." - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#diskTypeAggregatedList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "DiskTypeList": { - "id": "DiskTypeList", - "type": "object", - "description": "Contains a list of disk type resources.", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "array", - "description": "The disk type resources.", - "items": { - "$ref": "DiskType" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#diskTypeList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "DiskTypesScopedList": { - "id": "DiskTypesScopedList", - "type": "object", - "properties": { - "diskTypes": { - "type": "array", - "description": "List of disk types contained in this scope.", - "items": { - "$ref": "DiskType" - } - }, - "warning": { - "type": "object", - "description": "Informational warning which replaces the list of disk types when the list is empty.", - "properties": { - "code": { - "type": "string", - "description": "The warning type identifier for this warning.", - "enum": [ - "DEPRECATED_RESOURCE_USED", - "DISK_SIZE_LARGER_THAN_IMAGE_SIZE", - "INJECTED_KERNELS_DEPRECATED", - "NEXT_HOP_ADDRESS_NOT_ASSIGNED", - "NEXT_HOP_CANNOT_IP_FORWARD", - "NEXT_HOP_INSTANCE_NOT_FOUND", - "NEXT_HOP_INSTANCE_NOT_ON_NETWORK", - "NEXT_HOP_NOT_RUNNING", - "NO_RESULTS_ON_PAGE", - "REQUIRED_TOS_AGREEMENT", - "RESOURCE_NOT_DELETED", - "UNREACHABLE" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "data": { - "type": "array", - "description": "Metadata for this warning in 'key: value' format.", - "items": { - "type": "object", - "properties": { - "key": { - "type": "string", - "description": "A key for the warning data." - }, - "value": { - "type": "string", - "description": "A warning data value corresponding to the key." - } - } - } - }, - "message": { - "type": "string", - "description": "Optional human-readable details for this warning." - } - } - } - } - }, - "DisksScopedList": { - "id": "DisksScopedList", - "type": "object", - "properties": { - "disks": { - "type": "array", - "description": "List of disks contained in this scope.", - "items": { - "$ref": "Disk" - } - }, - "warning": { - "type": "object", - "description": "Informational warning which replaces the list of disks when the list is empty.", - "properties": { - "code": { - "type": "string", - "description": "The warning type identifier for this warning.", - "enum": [ - "DEPRECATED_RESOURCE_USED", - "DISK_SIZE_LARGER_THAN_IMAGE_SIZE", - "INJECTED_KERNELS_DEPRECATED", - "NEXT_HOP_ADDRESS_NOT_ASSIGNED", - "NEXT_HOP_CANNOT_IP_FORWARD", - "NEXT_HOP_INSTANCE_NOT_FOUND", - "NEXT_HOP_INSTANCE_NOT_ON_NETWORK", - "NEXT_HOP_NOT_RUNNING", - "NO_RESULTS_ON_PAGE", - "REQUIRED_TOS_AGREEMENT", - "RESOURCE_NOT_DELETED", - "UNREACHABLE" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "data": { - "type": "array", - "description": "Metadata for this warning in 'key: value' format.", - "items": { - "type": "object", - "properties": { - "key": { - "type": "string", - "description": "A key for the warning data." - }, - "value": { - "type": "string", - "description": "A warning data value corresponding to the key." - } - } - } - }, - "message": { - "type": "string", - "description": "Optional human-readable details for this warning." - } - } - } - } - }, - "Firewall": { - "id": "Firewall", - "type": "object", - "description": "A firewall resource.", - "properties": { - "allowed": { - "type": "array", - "description": "The list of rules specified by this firewall. Each rule specifies a protocol and port-range tuple that describes a permitted connection.", - "items": { - "type": "object", - "properties": { - "IPProtocol": { - "type": "string", - "description": "Required; this is the IP protocol that is allowed for this rule. This can either be one of the following well known protocol strings [\"tcp\", \"udp\", \"icmp\", \"esp\", \"ah\", \"sctp\"], or the IP protocol number." - }, - "ports": { - "type": "array", - "description": "An optional list of ports which are allowed. It is an error to specify this for any protocol that isn't UDP or TCP. Each entry must be either an integer or a range. If not specified, connections through any port are allowed.\n\nExample inputs include: [\"22\"], [\"80\",\"443\"] and [\"12345-12349\"].", - "items": { - "type": "string" - } - } - } - } - }, - "creationTimestamp": { - "type": "string", - "description": "Creation timestamp in RFC3339 text format (output only)." - }, - "description": { - "type": "string", - "description": "An optional textual description of the resource; provided by the client when the resource is created." - }, - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only).", - "format": "uint64" - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#firewall" - }, - "name": { - "type": "string", - "description": "Name of the resource; provided by the client when the resource is created. The name must be 1-63 characters long, and comply with RFC1035.", - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "annotations": { - "required": [ - "compute.firewalls.insert", - "compute.firewalls.patch" - ] - } - }, - "network": { - "type": "string", - "description": "URL of the network to which this firewall is applied; provided by the client when the firewall is created." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - }, - "sourceRanges": { - "type": "array", - "description": "A list of IP address blocks expressed in CIDR format which this rule applies to. One or both of sourceRanges and sourceTags may be set; an inbound connection is allowed if either the range or the tag of the source matches.", - "items": { - "type": "string" - } - }, - "sourceTags": { - "type": "array", - "description": "A list of instance tags which this rule applies to. One or both of sourceRanges and sourceTags may be set; an inbound connection is allowed if either the range or the tag of the source matches.", - "items": { - "type": "string" - } - }, - "targetTags": { - "type": "array", - "description": "A list of instance tags indicating sets of instances located on network which may make network connections as specified in allowed. If no targetTags are specified, the firewall rule applies to all instances on the specified network.", - "items": { - "type": "string" - } - } - } - }, - "FirewallList": { - "id": "FirewallList", - "type": "object", - "description": "Contains a list of firewall resources.", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "array", - "description": "The firewall resources.", - "items": { - "$ref": "Firewall" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#firewallList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "ForwardingRule": { - "id": "ForwardingRule", - "type": "object", - "description": "A ForwardingRule resource. A ForwardingRule resource specifies which pool of target VMs to forward a packet to if it matches the given [IPAddress, IPProtocol, portRange] tuple.", - "properties": { - "IPAddress": { - "type": "string", - "description": "Value of the reserved IP address that this forwarding rule is serving on behalf of. For global forwarding rules, the address must be a global IP; for regional forwarding rules, the address must live in the same region as the forwarding rule. If left empty (default value), an ephemeral IP from the same scope (global or regional) will be assigned." - }, - "IPProtocol": { - "type": "string", - "description": "The IP protocol to which this rule applies, valid options are 'TCP', 'UDP', 'ESP', 'AH' or 'SCTP'.", - "enum": [ - "AH", - "ESP", - "SCTP", - "TCP", - "UDP" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "" - ] - }, - "creationTimestamp": { - "type": "string", - "description": "Creation timestamp in RFC3339 text format (output only)." - }, - "description": { - "type": "string", - "description": "An optional textual description of the resource; provided by the client when the resource is created." - }, - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only).", - "format": "uint64" - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#forwardingRule" - }, - "name": { - "type": "string", - "description": "Name of the resource; provided by the client when the resource is created. The name must be 1-63 characters long, and comply with RFC1035.", - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?" - }, - "portRange": { - "type": "string", - "description": "Applicable only when 'IPProtocol' is 'TCP', 'UDP' or 'SCTP', only packets addressed to ports in the specified range will be forwarded to 'target'. If 'portRange' is left empty (default value), all ports are forwarded. Forwarding rules with the same [IPAddress, IPProtocol] pair must have disjoint port ranges." - }, - "region": { - "type": "string", - "description": "URL of the region where the regional forwarding rule resides (output only). This field is not applicable to global forwarding rules." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - }, - "target": { - "type": "string", - "description": "The URL of the target resource to receive the matched traffic. For regional forwarding rules, this target must live in the same region as the forwarding rule. For global forwarding rules, this target must be a global TargetHttpProxy resource." - } - } - }, - "ForwardingRuleAggregatedList": { - "id": "ForwardingRuleAggregatedList", - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "object", - "description": "A map of scoped forwarding rule lists.", - "additionalProperties": { - "$ref": "ForwardingRulesScopedList", - "description": "Name of the scope containing this set of addresses." - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#forwardingRuleAggregatedList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "ForwardingRuleList": { - "id": "ForwardingRuleList", - "type": "object", - "description": "Contains a list of ForwardingRule resources.", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "array", - "description": "The ForwardingRule resources.", - "items": { - "$ref": "ForwardingRule" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#forwardingRuleList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "ForwardingRulesScopedList": { - "id": "ForwardingRulesScopedList", - "type": "object", - "properties": { - "forwardingRules": { - "type": "array", - "description": "List of forwarding rules contained in this scope.", - "items": { - "$ref": "ForwardingRule" - } - }, - "warning": { - "type": "object", - "description": "Informational warning which replaces the list of forwarding rules when the list is empty.", - "properties": { - "code": { - "type": "string", - "description": "The warning type identifier for this warning.", - "enum": [ - "DEPRECATED_RESOURCE_USED", - "DISK_SIZE_LARGER_THAN_IMAGE_SIZE", - "INJECTED_KERNELS_DEPRECATED", - "NEXT_HOP_ADDRESS_NOT_ASSIGNED", - "NEXT_HOP_CANNOT_IP_FORWARD", - "NEXT_HOP_INSTANCE_NOT_FOUND", - "NEXT_HOP_INSTANCE_NOT_ON_NETWORK", - "NEXT_HOP_NOT_RUNNING", - "NO_RESULTS_ON_PAGE", - "REQUIRED_TOS_AGREEMENT", - "RESOURCE_NOT_DELETED", - "UNREACHABLE" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "data": { - "type": "array", - "description": "Metadata for this warning in 'key: value' format.", - "items": { - "type": "object", - "properties": { - "key": { - "type": "string", - "description": "A key for the warning data." - }, - "value": { - "type": "string", - "description": "A warning data value corresponding to the key." - } - } - } - }, - "message": { - "type": "string", - "description": "Optional human-readable details for this warning." - } - } - } - } - }, - "HealthCheckReference": { - "id": "HealthCheckReference", - "type": "object", - "properties": { - "healthCheck": { - "type": "string" - } - } - }, - "HealthStatus": { - "id": "HealthStatus", - "type": "object", - "properties": { - "healthState": { - "type": "string", - "description": "Health state of the instance.", - "enum": [ - "HEALTHY", - "UNHEALTHY" - ], - "enumDescriptions": [ - "", - "" - ] - }, - "instance": { - "type": "string", - "description": "URL of the instance resource." - }, - "ipAddress": { - "type": "string", - "description": "The IP address represented by this resource." - }, - "port": { - "type": "integer", - "description": "The port on the instance.", - "format": "int32" - } - } - }, - "HostRule": { - "id": "HostRule", - "type": "object", - "description": "A host-matching rule for a URL. If matched, will use the named PathMatcher to select the BackendService.", - "properties": { - "description": { - "type": "string" - }, - "hosts": { - "type": "array", - "description": "The list of host patterns to match. They must be valid hostnames except that they may start with *. or *-. The * acts like a glob and will match any string of atoms (separated by .s and -s) to the left.", - "items": { - "type": "string" - } - }, - "pathMatcher": { - "type": "string", - "description": "The name of the PathMatcher to match the path portion of the URL, if the this HostRule matches the URL's host portion." - } - } - }, - "HttpHealthCheck": { - "id": "HttpHealthCheck", - "type": "object", - "description": "An HttpHealthCheck resource. This resource defines a template for how individual VMs should be checked for health, via HTTP.", - "properties": { - "checkIntervalSec": { - "type": "integer", - "description": "How often (in seconds) to send a health check. The default value is 5 seconds.", - "format": "int32" - }, - "creationTimestamp": { - "type": "string", - "description": "Creation timestamp in RFC3339 text format (output only)." - }, - "description": { - "type": "string", - "description": "An optional textual description of the resource; provided by the client when the resource is created." - }, - "healthyThreshold": { - "type": "integer", - "description": "A so-far unhealthy VM will be marked healthy after this many consecutive successes. The default value is 2.", - "format": "int32" - }, - "host": { - "type": "string", - "description": "The value of the host header in the HTTP health check request. If left empty (default value), the public IP on behalf of which this health check is performed will be used." - }, - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only).", - "format": "uint64" - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#httpHealthCheck" - }, - "name": { - "type": "string", - "description": "Name of the resource; provided by the client when the resource is created. The name must be 1-63 characters long, and comply with RFC1035.", - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?" - }, - "port": { - "type": "integer", - "description": "The TCP port number for the HTTP health check request. The default value is 80.", - "format": "int32" - }, - "requestPath": { - "type": "string", - "description": "The request path of the HTTP health check request. The default value is \"/\"." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - }, - "timeoutSec": { - "type": "integer", - "description": "How long (in seconds) to wait before claiming failure. The default value is 5 seconds.", - "format": "int32" - }, - "unhealthyThreshold": { - "type": "integer", - "description": "A so-far healthy VM will be marked unhealthy after this many consecutive failures. The default value is 2.", - "format": "int32" - } - } - }, - "HttpHealthCheckList": { - "id": "HttpHealthCheckList", - "type": "object", - "description": "Contains a list of HttpHealthCheck resources.", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "array", - "description": "The HttpHealthCheck resources.", - "items": { - "$ref": "HttpHealthCheck" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#httpHealthCheckList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "Image": { - "id": "Image", - "type": "object", - "description": "A disk image resource.", - "properties": { - "archiveSizeBytes": { - "type": "string", - "description": "Size of the image tar.gz archive stored in Google Cloud Storage (in bytes).", - "format": "int64" - }, - "creationTimestamp": { - "type": "string", - "description": "Creation timestamp in RFC3339 text format (output only)." - }, - "deprecated": { - "$ref": "DeprecationStatus", - "description": "The deprecation status associated with this image." - }, - "description": { - "type": "string", - "description": "Textual description of the resource; provided by the client when the resource is created." - }, - "diskSizeGb": { - "type": "string", - "description": "Size of the image when restored onto a disk (in GiB).", - "format": "int64" - }, - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only).", - "format": "uint64" - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#image" - }, - "licenses": { - "type": "array", - "description": "Public visible licenses.", - "items": { - "type": "string" - } - }, - "name": { - "type": "string", - "description": "Name of the resource; provided by the client when the resource is created. The name must be 1-63 characters long, and comply with RFC1035.", - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "annotations": { - "required": [ - "compute.images.insert" - ] - } - }, - "rawDisk": { - "type": "object", - "description": "The raw disk image parameters.", - "properties": { - "containerType": { - "type": "string", - "description": "The format used to encode and transmit the block device. Should be TAR. This is just a container and transmission format and not a runtime format. Provided by the client when the disk image is created.", - "enum": [ - "TAR" - ], - "enumDescriptions": [ - "" - ] - }, - "sha1Checksum": { - "type": "string", - "description": "An optional SHA1 checksum of the disk image before unpackaging; provided by the client when the disk image is created.", - "pattern": "[a-f0-9]{40}" - }, - "source": { - "type": "string", - "description": "The full Google Cloud Storage URL where the disk image is stored; provided by the client when the disk image is created.", - "annotations": { - "required": [ - "compute.images.insert" - ] - } - } - } - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - }, - "sourceDisk": { - "type": "string", - "description": "The source disk used to create this image." - }, - "sourceDiskId": { - "type": "string", - "description": "The 'id' value of the disk used to create this image. This value may be used to determine whether the image was taken from the current or a previous instance of a given disk name." - }, - "sourceType": { - "type": "string", - "description": "Must be \"RAW\"; provided by the client when the disk image is created.", - "default": "RAW", - "enum": [ - "RAW" - ], - "enumDescriptions": [ - "" - ] - }, - "status": { - "type": "string", - "description": "Status of the image (output only). It will be one of the following READY - after image has been successfully created and is ready for use FAILED - if creating the image fails for some reason PENDING - the image creation is in progress An image can be used to create other resources suck as instances only after the image has been successfully created and the status is set to READY.", - "enum": [ - "FAILED", - "PENDING", - "READY" - ], - "enumDescriptions": [ - "", - "", - "" - ] - } - } - }, - "ImageList": { - "id": "ImageList", - "type": "object", - "description": "Contains a list of disk image resources.", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "array", - "description": "The disk image resources.", - "items": { - "$ref": "Image" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#imageList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "Instance": { - "id": "Instance", - "type": "object", - "description": "An instance resource.", - "properties": { - "canIpForward": { - "type": "boolean", - "description": "Allows this instance to send packets with source IP addresses other than its own and receive packets with destination IP addresses other than its own. If this instance will be used as an IP gateway or it will be set as the next-hop in a Route resource, say true. If unsure, leave this set to false." - }, - "creationTimestamp": { - "type": "string", - "description": "Creation timestamp in RFC3339 text format (output only)." - }, - "description": { - "type": "string", - "description": "An optional textual description of the resource; provided by the client when the resource is created." - }, - "disks": { - "type": "array", - "description": "Array of disks associated with this instance. Persistent disks must be created before you can assign them.", - "items": { - "$ref": "AttachedDisk" - } - }, - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only).", - "format": "uint64" - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#instance" - }, - "machineType": { - "type": "string", - "description": "URL of the machine type resource describing which machine type to use to host the instance; provided by the client when the instance is created.", - "annotations": { - "required": [ - "compute.instances.insert" - ] - } - }, - "metadata": { - "$ref": "Metadata", - "description": "Metadata key/value pairs assigned to this instance. Consists of custom metadata or predefined keys; see Instance documentation for more information." - }, - "name": { - "type": "string", - "description": "Name of the resource; provided by the client when the resource is created. The name must be 1-63 characters long, and comply with RFC1035.", - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "annotations": { - "required": [ - "compute.instances.insert" - ] - } - }, - "networkInterfaces": { - "type": "array", - "description": "Array of configurations for this interface. This specifies how this interface is configured to interact with other network services, such as connecting to the internet. Currently, ONE_TO_ONE_NAT is the only access config supported. If there are no accessConfigs specified, then this instance will have no external internet access.", - "items": { - "$ref": "NetworkInterface" - } - }, - "scheduling": { - "$ref": "Scheduling", - "description": "Scheduling options for this instance." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - }, - "serviceAccounts": { - "type": "array", - "description": "A list of service accounts each with specified scopes, for which access tokens are to be made available to the instance through metadata queries.", - "items": { - "$ref": "ServiceAccount" - } - }, - "status": { - "type": "string", - "description": "Instance status. One of the following values: \"PROVISIONING\", \"STAGING\", \"RUNNING\", \"STOPPING\", \"STOPPED\", \"TERMINATED\" (output only).", - "enum": [ - "PROVISIONING", - "RUNNING", - "STAGING", - "STOPPED", - "STOPPING", - "TERMINATED" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "" - ] - }, - "statusMessage": { - "type": "string", - "description": "An optional, human-readable explanation of the status (output only)." - }, - "tags": { - "$ref": "Tags", - "description": "A list of tags to be applied to this instance. Used to identify valid sources or targets for network firewalls. Provided by the client on instance creation. The tags can be later modified by the setTags method. Each tag within the list must comply with RFC1035." - }, - "zone": { - "type": "string", - "description": "URL of the zone where the instance resides (output only)." - } - } - }, - "InstanceAggregatedList": { - "id": "InstanceAggregatedList", - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "object", - "description": "A map of scoped instance lists.", - "additionalProperties": { - "$ref": "InstancesScopedList", - "description": "Name of the scope containing this set of instances." - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#instanceAggregatedList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "InstanceList": { - "id": "InstanceList", - "type": "object", - "description": "Contains a list of instance resources.", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "array", - "description": "A list of instance resources.", - "items": { - "$ref": "Instance" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#instanceList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "InstanceProperties": { - "id": "InstanceProperties", - "type": "object", - "description": "", - "properties": { - "canIpForward": { - "type": "boolean", - "description": "Allows instances created based on this template to send packets with source IP addresses other than their own and receive packets with destination IP addresses other than their own. If these instances will be used as an IP gateway or it will be set as the next-hop in a Route resource, say true. If unsure, leave this set to false." - }, - "description": { - "type": "string", - "description": "An optional textual description for the instances created based on the instance template resource; provided by the client when the template is created." - }, - "disks": { - "type": "array", - "description": "Array of disks associated with instance created based on this template.", - "items": { - "$ref": "AttachedDisk" - } - }, - "machineType": { - "type": "string", - "description": "Name of the machine type resource describing which machine type to use to host the instances created based on this template; provided by the client when the instance template is created.", - "annotations": { - "required": [ - "compute.instanceTemplates.insert" - ] - } - }, - "metadata": { - "$ref": "Metadata", - "description": "Metadata key/value pairs assigned to instances created based on this template. Consists of custom metadata or predefined keys; see Instance documentation for more information." - }, - "networkInterfaces": { - "type": "array", - "description": "Array of configurations for this interface. This specifies how this interface is configured to interact with other network services, such as connecting to the internet. Currently, ONE_TO_ONE_NAT is the only access config supported. If there are no accessConfigs specified, then this instances created based based on this template will have no external internet access.", - "items": { - "$ref": "NetworkInterface" - } - }, - "scheduling": { - "$ref": "Scheduling", - "description": "Scheduling options for the instances created based on this template." - }, - "serviceAccounts": { - "type": "array", - "description": "A list of service accounts each with specified scopes, for which access tokens are to be made available to the instances created based on this template, through metadata queries.", - "items": { - "$ref": "ServiceAccount" - } - }, - "tags": { - "$ref": "Tags", - "description": "A list of tags to be applied to the instances created based on this template used to identify valid sources or targets for network firewalls. Provided by the client on instance creation. The tags can be later modified by the setTags method. Each tag within the list must comply with RFC1035." - } - } - }, - "InstanceReference": { - "id": "InstanceReference", - "type": "object", - "properties": { - "instance": { - "type": "string" - } - } - }, - "InstanceTemplate": { - "id": "InstanceTemplate", - "type": "object", - "description": "An Instance Template resource.", - "properties": { - "creationTimestamp": { - "type": "string", - "description": "Creation timestamp in RFC3339 text format (output only)." - }, - "description": { - "type": "string", - "description": "An optional textual description of the instance template resource; provided by the client when the resource is created." - }, - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only).", - "format": "uint64" - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#instanceTemplate" - }, - "name": { - "type": "string", - "description": "Name of the instance template resource; provided by the client when the resource is created. The name must be 1-63 characters long, and comply with RFC1035", - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "annotations": { - "required": [ - "compute.instanceTemplates.insert" - ] - } - }, - "properties": { - "$ref": "InstanceProperties", - "description": "The instance properties portion of this instance template resource." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - } - } - }, - "InstanceTemplateList": { - "id": "InstanceTemplateList", - "type": "object", - "description": "Contains a list of instance template resources.", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "array", - "description": "A list of instance template resources.", - "items": { - "$ref": "InstanceTemplate" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#instanceTemplateList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "InstancesScopedList": { - "id": "InstancesScopedList", - "type": "object", - "properties": { - "instances": { - "type": "array", - "description": "List of instances contained in this scope.", - "items": { - "$ref": "Instance" - } - }, - "warning": { - "type": "object", - "description": "Informational warning which replaces the list of instances when the list is empty.", - "properties": { - "code": { - "type": "string", - "description": "The warning type identifier for this warning.", - "enum": [ - "DEPRECATED_RESOURCE_USED", - "DISK_SIZE_LARGER_THAN_IMAGE_SIZE", - "INJECTED_KERNELS_DEPRECATED", - "NEXT_HOP_ADDRESS_NOT_ASSIGNED", - "NEXT_HOP_CANNOT_IP_FORWARD", - "NEXT_HOP_INSTANCE_NOT_FOUND", - "NEXT_HOP_INSTANCE_NOT_ON_NETWORK", - "NEXT_HOP_NOT_RUNNING", - "NO_RESULTS_ON_PAGE", - "REQUIRED_TOS_AGREEMENT", - "RESOURCE_NOT_DELETED", - "UNREACHABLE" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "data": { - "type": "array", - "description": "Metadata for this warning in 'key: value' format.", - "items": { - "type": "object", - "properties": { - "key": { - "type": "string", - "description": "A key for the warning data." - }, - "value": { - "type": "string", - "description": "A warning data value corresponding to the key." - } - } - } - }, - "message": { - "type": "string", - "description": "Optional human-readable details for this warning." - } - } - } - } - }, - "License": { - "id": "License", - "type": "object", - "description": "A license resource.", - "properties": { - "chargesUseFee": { - "type": "boolean", - "description": "If true, the customer will be charged license fee for running software that contains this license on an instance." - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#license" - }, - "name": { - "type": "string", - "description": "Name of the resource; provided by the client when the resource is created. The name must be 1-63 characters long, and comply with RFC1035.", - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "annotations": { - "required": [ - "compute.images.insert" - ] - } - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - } - } - }, - "MachineType": { - "id": "MachineType", - "type": "object", - "description": "A machine type resource.", - "properties": { - "creationTimestamp": { - "type": "string", - "description": "Creation timestamp in RFC3339 text format (output only)." - }, - "deprecated": { - "$ref": "DeprecationStatus", - "description": "The deprecation status associated with this machine type." - }, - "description": { - "type": "string", - "description": "An optional textual description of the resource." - }, - "guestCpus": { - "type": "integer", - "description": "Count of CPUs exposed to the instance.", - "format": "int32" - }, - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only).", - "format": "uint64" - }, - "imageSpaceGb": { - "type": "integer", - "description": "Space allotted for the image, defined in GB.", - "format": "int32" - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#machineType" - }, - "maximumPersistentDisks": { - "type": "integer", - "description": "Maximum persistent disks allowed.", - "format": "int32" - }, - "maximumPersistentDisksSizeGb": { - "type": "string", - "description": "Maximum total persistent disks size (GB) allowed.", - "format": "int64" - }, - "memoryMb": { - "type": "integer", - "description": "Physical memory assigned to the instance, defined in MB.", - "format": "int32" - }, - "name": { - "type": "string", - "description": "Name of the resource.", - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?" - }, - "scratchDisks": { - "type": "array", - "description": "List of extended scratch disks assigned to the instance.", - "items": { - "type": "object", - "properties": { - "diskGb": { - "type": "integer", - "description": "Size of the scratch disk, defined in GB.", - "format": "int32" - } - } - } - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - }, - "zone": { - "type": "string", - "description": "Url of the zone where the machine type resides (output only)." - } - } - }, - "MachineTypeAggregatedList": { - "id": "MachineTypeAggregatedList", - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "object", - "description": "A map of scoped machine type lists.", - "additionalProperties": { - "$ref": "MachineTypesScopedList", - "description": "Name of the scope containing this set of machine types." - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#machineTypeAggregatedList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "MachineTypeList": { - "id": "MachineTypeList", - "type": "object", - "description": "Contains a list of machine type resources.", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "array", - "description": "The machine type resources.", - "items": { - "$ref": "MachineType" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#machineTypeList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "MachineTypesScopedList": { - "id": "MachineTypesScopedList", - "type": "object", - "properties": { - "machineTypes": { - "type": "array", - "description": "List of machine types contained in this scope.", - "items": { - "$ref": "MachineType" - } - }, - "warning": { - "type": "object", - "description": "Informational warning which replaces the list of machine types when the list is empty.", - "properties": { - "code": { - "type": "string", - "description": "The warning type identifier for this warning.", - "enum": [ - "DEPRECATED_RESOURCE_USED", - "DISK_SIZE_LARGER_THAN_IMAGE_SIZE", - "INJECTED_KERNELS_DEPRECATED", - "NEXT_HOP_ADDRESS_NOT_ASSIGNED", - "NEXT_HOP_CANNOT_IP_FORWARD", - "NEXT_HOP_INSTANCE_NOT_FOUND", - "NEXT_HOP_INSTANCE_NOT_ON_NETWORK", - "NEXT_HOP_NOT_RUNNING", - "NO_RESULTS_ON_PAGE", - "REQUIRED_TOS_AGREEMENT", - "RESOURCE_NOT_DELETED", - "UNREACHABLE" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "data": { - "type": "array", - "description": "Metadata for this warning in 'key: value' format.", - "items": { - "type": "object", - "properties": { - "key": { - "type": "string", - "description": "A key for the warning data." - }, - "value": { - "type": "string", - "description": "A warning data value corresponding to the key." - } - } - } - }, - "message": { - "type": "string", - "description": "Optional human-readable details for this warning." - } - } - } - } - }, - "Metadata": { - "id": "Metadata", - "type": "object", - "description": "A metadata key/value entry.", - "properties": { - "fingerprint": { - "type": "string", - "description": "Fingerprint of this resource. A hash of the metadata's contents. This field is used for optimistic locking. An up-to-date metadata fingerprint must be provided in order to modify metadata.", - "format": "byte" - }, - "items": { - "type": "array", - "description": "Array of key/value pairs. The total size of all keys and values must be less than 512 KB.", - "items": { - "type": "object", - "properties": { - "key": { - "type": "string", - "description": "Key for the metadata entry. Keys must conform to the following regexp: [a-zA-Z0-9-_]+, and be less than 128 bytes in length. This is reflected as part of a URL in the metadata server. Additionally, to avoid ambiguity, keys must not conflict with any other metadata keys for the project.", - "pattern": "[a-zA-Z0-9-_]{1,128}", - "annotations": { - "required": [ - "compute.instances.insert", - "compute.projects.setCommonInstanceMetadata" - ] - } - }, - "value": { - "type": "string", - "description": "Value for the metadata entry. These are free-form strings, and only have meaning as interpreted by the image running in the instance. The only restriction placed on values is that their size must be less than or equal to 32768 bytes.", - "annotations": { - "required": [ - "compute.instances.insert", - "compute.projects.setCommonInstanceMetadata" - ] - } - } - } - } - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#metadata" - } - } - }, - "Network": { - "id": "Network", - "type": "object", - "description": "A network resource.", - "properties": { - "IPv4Range": { - "type": "string", - "description": "Required; The range of internal addresses that are legal on this network. This range is a CIDR specification, for example: 192.168.0.0/16. Provided by the client when the network is created.", - "pattern": "[0-9]{1,3}(?:\\.[0-9]{1,3}){3}/[0-9]{1,2}", - "annotations": { - "required": [ - "compute.networks.insert" - ] - } - }, - "creationTimestamp": { - "type": "string", - "description": "Creation timestamp in RFC3339 text format (output only)." - }, - "description": { - "type": "string", - "description": "An optional textual description of the resource; provided by the client when the resource is created." - }, - "gatewayIPv4": { - "type": "string", - "description": "An optional address that is used for default routing to other networks. This must be within the range specified by IPv4Range, and is typically the first usable address in that range. If not specified, the default value is the first usable address in IPv4Range.", - "pattern": "[0-9]{1,3}(?:\\.[0-9]{1,3}){3}" - }, - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only).", - "format": "uint64" - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#network" - }, - "name": { - "type": "string", - "description": "Name of the resource; provided by the client when the resource is created. The name must be 1-63 characters long, and comply with RFC1035.", - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "annotations": { - "required": [ - "compute.networks.insert" - ] - } - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - } - } - }, - "NetworkInterface": { - "id": "NetworkInterface", - "type": "object", - "description": "A network interface resource attached to an instance.", - "properties": { - "accessConfigs": { - "type": "array", - "description": "Array of configurations for this interface. This specifies how this interface is configured to interact with other network services, such as connecting to the internet. Currently, ONE_TO_ONE_NAT is the only access config supported. If there are no accessConfigs specified, then this instance will have no external internet access.", - "items": { - "$ref": "AccessConfig" - } - }, - "name": { - "type": "string", - "description": "Name of the network interface, determined by the server; for network devices, these are e.g. eth0, eth1, etc. (output only)." - }, - "network": { - "type": "string", - "description": "URL of the network resource attached to this interface.", - "annotations": { - "required": [ - "compute.instances.insert" - ] - } - }, - "networkIP": { - "type": "string", - "description": "An optional IPV4 internal network address assigned to the instance for this network interface (output only)." - } - } - }, - "NetworkList": { - "id": "NetworkList", - "type": "object", - "description": "Contains a list of network resources.", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "array", - "description": "The network resources.", - "items": { - "$ref": "Network" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#networkList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "Operation": { - "id": "Operation", - "type": "object", - "description": "An operation resource, used to manage asynchronous API requests.", - "properties": { - "clientOperationId": { - "type": "string", - "description": "An optional identifier specified by the client when the mutation was initiated. Must be unique for all operation resources in the project (output only)." - }, - "creationTimestamp": { - "type": "string", - "description": "Creation timestamp in RFC3339 text format (output only)." - }, - "endTime": { - "type": "string", - "description": "The time that this operation was completed. This is in RFC 3339 format (output only)." - }, - "error": { - "type": "object", - "description": "If errors occurred during processing of this operation, this field will be populated (output only).", - "properties": { - "errors": { - "type": "array", - "description": "The array of errors encountered while processing this operation.", - "items": { - "type": "object", - "properties": { - "code": { - "type": "string", - "description": "The error type identifier for this error." - }, - "location": { - "type": "string", - "description": "Indicates the field in the request which caused the error. This property is optional." - }, - "message": { - "type": "string", - "description": "An optional, human-readable error message." - } - } - } - } - } - }, - "httpErrorMessage": { - "type": "string", - "description": "If operation fails, the HTTP error message returned, e.g. NOT FOUND. (output only)." - }, - "httpErrorStatusCode": { - "type": "integer", - "description": "If operation fails, the HTTP error status code returned, e.g. 404. (output only).", - "format": "int32" - }, - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only).", - "format": "uint64" - }, - "insertTime": { - "type": "string", - "description": "The time that this operation was requested. This is in RFC 3339 format (output only)." - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#operation" - }, - "name": { - "type": "string", - "description": "Name of the resource (output only)." - }, - "operationType": { - "type": "string", - "description": "Type of the operation. Examples include \"insert\", \"update\", and \"delete\" (output only)." - }, - "progress": { - "type": "integer", - "description": "An optional progress indicator that ranges from 0 to 100. There is no requirement that this be linear or support any granularity of operations. This should not be used to guess at when the operation will be complete. This number should be monotonically increasing as the operation progresses (output only).", - "format": "int32" - }, - "region": { - "type": "string", - "description": "URL of the region where the operation resides (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - }, - "startTime": { - "type": "string", - "description": "The time that this operation was started by the server. This is in RFC 3339 format (output only)." - }, - "status": { - "type": "string", - "description": "Status of the operation. Can be one of the following: \"PENDING\", \"RUNNING\", or \"DONE\" (output only).", - "enum": [ - "DONE", - "PENDING", - "RUNNING" - ], - "enumDescriptions": [ - "", - "", - "" - ] - }, - "statusMessage": { - "type": "string", - "description": "An optional textual description of the current status of the operation (output only)." - }, - "targetId": { - "type": "string", - "description": "Unique target id which identifies a particular incarnation of the target (output only).", - "format": "uint64" - }, - "targetLink": { - "type": "string", - "description": "URL of the resource the operation is mutating (output only)." - }, - "user": { - "type": "string", - "description": "User who requested the operation, for example \"user@example.com\" (output only)." - }, - "warnings": { - "type": "array", - "description": "If warning messages generated during processing of this operation, this field will be populated (output only).", - "items": { - "type": "object", - "properties": { - "code": { - "type": "string", - "description": "The warning type identifier for this warning.", - "enum": [ - "DEPRECATED_RESOURCE_USED", - "DISK_SIZE_LARGER_THAN_IMAGE_SIZE", - "INJECTED_KERNELS_DEPRECATED", - "NEXT_HOP_ADDRESS_NOT_ASSIGNED", - "NEXT_HOP_CANNOT_IP_FORWARD", - "NEXT_HOP_INSTANCE_NOT_FOUND", - "NEXT_HOP_INSTANCE_NOT_ON_NETWORK", - "NEXT_HOP_NOT_RUNNING", - "NO_RESULTS_ON_PAGE", - "REQUIRED_TOS_AGREEMENT", - "RESOURCE_NOT_DELETED", - "UNREACHABLE" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "data": { - "type": "array", - "description": "Metadata for this warning in 'key: value' format.", - "items": { - "type": "object", - "properties": { - "key": { - "type": "string", - "description": "A key for the warning data." - }, - "value": { - "type": "string", - "description": "A warning data value corresponding to the key." - } - } - } - }, - "message": { - "type": "string", - "description": "Optional human-readable details for this warning." - } - } - } - }, - "zone": { - "type": "string", - "description": "URL of the zone where the operation resides (output only)." - } - } - }, - "OperationAggregatedList": { - "id": "OperationAggregatedList", - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "object", - "description": "A map of scoped operation lists.", - "additionalProperties": { - "$ref": "OperationsScopedList", - "description": "Name of the scope containing this set of operations." - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#operationAggregatedList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "OperationList": { - "id": "OperationList", - "type": "object", - "description": "Contains a list of operation resources.", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "array", - "description": "The operation resources.", - "items": { - "$ref": "Operation" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#operationList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "OperationsScopedList": { - "id": "OperationsScopedList", - "type": "object", - "properties": { - "operations": { - "type": "array", - "description": "List of operations contained in this scope.", - "items": { - "$ref": "Operation" - } - }, - "warning": { - "type": "object", - "description": "Informational warning which replaces the list of operations when the list is empty.", - "properties": { - "code": { - "type": "string", - "description": "The warning type identifier for this warning.", - "enum": [ - "DEPRECATED_RESOURCE_USED", - "DISK_SIZE_LARGER_THAN_IMAGE_SIZE", - "INJECTED_KERNELS_DEPRECATED", - "NEXT_HOP_ADDRESS_NOT_ASSIGNED", - "NEXT_HOP_CANNOT_IP_FORWARD", - "NEXT_HOP_INSTANCE_NOT_FOUND", - "NEXT_HOP_INSTANCE_NOT_ON_NETWORK", - "NEXT_HOP_NOT_RUNNING", - "NO_RESULTS_ON_PAGE", - "REQUIRED_TOS_AGREEMENT", - "RESOURCE_NOT_DELETED", - "UNREACHABLE" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "data": { - "type": "array", - "description": "Metadata for this warning in 'key: value' format.", - "items": { - "type": "object", - "properties": { - "key": { - "type": "string", - "description": "A key for the warning data." - }, - "value": { - "type": "string", - "description": "A warning data value corresponding to the key." - } - } - } - }, - "message": { - "type": "string", - "description": "Optional human-readable details for this warning." - } - } - } - } - }, - "PathMatcher": { - "id": "PathMatcher", - "type": "object", - "description": "A matcher for the path portion of the URL. The BackendService from the longest-matched rule will serve the URL. If no rule was matched, the default_service will be used.", - "properties": { - "defaultService": { - "type": "string", - "description": "The URL to the BackendService resource. This will be used if none of the 'pathRules' defined by this PathMatcher is met by the URL's path portion." - }, - "description": { - "type": "string" - }, - "name": { - "type": "string", - "description": "The name to which this PathMatcher is referred by the HostRule." - }, - "pathRules": { - "type": "array", - "description": "The list of path rules.", - "items": { - "$ref": "PathRule" - } - } - } - }, - "PathRule": { - "id": "PathRule", - "type": "object", - "description": "A path-matching rule for a URL. If matched, will use the specified BackendService to handle the traffic arriving at this URL.", - "properties": { - "paths": { - "type": "array", - "description": "The list of path patterns to match. Each must start with / and the only place a * is allowed is at the end following a /. The string fed to the path matcher does not include any text after the first ? or #, and those chars are not allowed here.", - "items": { - "type": "string" - } - }, - "service": { - "type": "string", - "description": "The URL of the BackendService resource if this rule is matched." - } - } - }, - "Project": { - "id": "Project", - "type": "object", - "description": "A project resource. Projects can be created only in the APIs Console. Unless marked otherwise, values can only be modified in the console.", - "properties": { - "commonInstanceMetadata": { - "$ref": "Metadata", - "description": "Metadata key/value pairs available to all instances contained in this project." - }, - "creationTimestamp": { - "type": "string", - "description": "Creation timestamp in RFC3339 text format (output only)." - }, - "description": { - "type": "string", - "description": "An optional textual description of the resource." - }, - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only).", - "format": "uint64" - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#project" - }, - "name": { - "type": "string", - "description": "Name of the resource." - }, - "quotas": { - "type": "array", - "description": "Quotas assigned to this project.", - "items": { - "$ref": "Quota" - } - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - }, - "usageExportLocation": { - "$ref": "UsageExportLocation", - "description": "The location in Cloud Storage and naming method of the daily usage report." - } - } - }, - "Quota": { - "id": "Quota", - "type": "object", - "description": "A quotas entry.", - "properties": { - "limit": { - "type": "number", - "description": "Quota limit for this metric.", - "format": "double" - }, - "metric": { - "type": "string", - "description": "Name of the quota metric.", - "enum": [ - "BACKEND_SERVICES", - "CPUS", - "DISKS", - "DISKS_TOTAL_GB", - "EPHEMERAL_ADDRESSES", - "FIREWALLS", - "FORWARDING_RULES", - "HEALTH_CHECKS", - "IMAGES", - "IMAGES_TOTAL_GB", - "INSTANCES", - "IN_USE_ADDRESSES", - "KERNELS", - "KERNELS_TOTAL_GB", - "LOCAL_SSD_TOTAL_GB", - "NETWORKS", - "OPERATIONS", - "ROUTES", - "SNAPSHOTS", - "SSD_TOTAL_GB", - "STATIC_ADDRESSES", - "TARGET_HTTP_PROXIES", - "TARGET_INSTANCES", - "TARGET_POOLS", - "URL_MAPS" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "usage": { - "type": "number", - "description": "Current usage of this metric.", - "format": "double" - } - } - }, - "Region": { - "id": "Region", - "type": "object", - "description": "Region resource.", - "properties": { - "creationTimestamp": { - "type": "string", - "description": "Creation timestamp in RFC3339 text format (output only)." - }, - "deprecated": { - "$ref": "DeprecationStatus", - "description": "The deprecation status associated with this region." - }, - "description": { - "type": "string", - "description": "Textual description of the resource." - }, - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only).", - "format": "uint64" - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#region" - }, - "name": { - "type": "string", - "description": "Name of the resource." - }, - "quotas": { - "type": "array", - "description": "Quotas assigned to this region.", - "items": { - "$ref": "Quota" - } - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - }, - "status": { - "type": "string", - "description": "Status of the region, \"UP\" or \"DOWN\".", - "enum": [ - "DOWN", - "UP" - ], - "enumDescriptions": [ - "", - "" - ] - }, - "zones": { - "type": "array", - "description": "A list of zones homed in this region, in the form of resource URLs.", - "items": { - "type": "string" - } - } - } - }, - "RegionList": { - "id": "RegionList", - "type": "object", - "description": "Contains a list of region resources.", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "array", - "description": "The region resources.", - "items": { - "$ref": "Region" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#regionList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "ResourceGroupReference": { - "id": "ResourceGroupReference", - "type": "object", - "properties": { - "group": { - "type": "string", - "description": "A URI referencing one of the resource views listed in the backend service." - } - } - }, - "Route": { - "id": "Route", - "type": "object", - "description": "The route resource. A Route is a rule that specifies how certain packets should be handled by the virtual network. Routes are associated with VMs by tag and the set of Routes for a particular VM is called its routing table. For each packet leaving a VM, the system searches that VM's routing table for a single best matching Route. Routes match packets by destination IP address, preferring smaller or more specific ranges over larger ones. If there is a tie, the system selects the Route with the smallest priority value. If there is still a tie, it uses the layer three and four packet headers to select just one of the remaining matching Routes. The packet is then forwarded as specified by the next_hop field of the winning Route -- either to another VM destination, a VM gateway or a GCE operated gateway. Packets that do not match any Route in the sending VM's routing table will be dropped.", - "properties": { - "creationTimestamp": { - "type": "string", - "description": "Creation timestamp in RFC3339 text format (output only)." - }, - "description": { - "type": "string", - "description": "An optional textual description of the resource; provided by the client when the resource is created." - }, - "destRange": { - "type": "string", - "description": "Which packets does this route apply to?", - "annotations": { - "required": [ - "compute.routes.insert" - ] - } - }, - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only).", - "format": "uint64" - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#route" - }, - "name": { - "type": "string", - "description": "Name of the resource; provided by the client when the resource is created. The name must be 1-63 characters long, and comply with RFC1035.", - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "annotations": { - "required": [ - "compute.routes.insert" - ] - } - }, - "network": { - "type": "string", - "description": "URL of the network to which this route is applied; provided by the client when the route is created.", - "annotations": { - "required": [ - "compute.routes.insert" - ] - } - }, - "nextHopGateway": { - "type": "string", - "description": "The URL to a gateway that should handle matching packets." - }, - "nextHopInstance": { - "type": "string", - "description": "The URL to an instance that should handle matching packets." - }, - "nextHopIp": { - "type": "string", - "description": "The network IP address of an instance that should handle matching packets." - }, - "nextHopNetwork": { - "type": "string", - "description": "The URL of the local network if it should handle matching packets." - }, - "priority": { - "type": "integer", - "description": "Breaks ties between Routes of equal specificity. Routes with smaller values win when tied with routes with larger values.", - "format": "uint32", - "annotations": { - "required": [ - "compute.routes.insert" - ] - } - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - }, - "tags": { - "type": "array", - "description": "A list of instance tags to which this route applies.", - "items": { - "type": "string" - }, - "annotations": { - "required": [ - "compute.routes.insert" - ] - } - }, - "warnings": { - "type": "array", - "description": "If potential misconfigurations are detected for this route, this field will be populated with warning messages.", - "items": { - "type": "object", - "properties": { - "code": { - "type": "string", - "description": "The warning type identifier for this warning.", - "enum": [ - "DEPRECATED_RESOURCE_USED", - "DISK_SIZE_LARGER_THAN_IMAGE_SIZE", - "INJECTED_KERNELS_DEPRECATED", - "NEXT_HOP_ADDRESS_NOT_ASSIGNED", - "NEXT_HOP_CANNOT_IP_FORWARD", - "NEXT_HOP_INSTANCE_NOT_FOUND", - "NEXT_HOP_INSTANCE_NOT_ON_NETWORK", - "NEXT_HOP_NOT_RUNNING", - "NO_RESULTS_ON_PAGE", - "REQUIRED_TOS_AGREEMENT", - "RESOURCE_NOT_DELETED", - "UNREACHABLE" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "data": { - "type": "array", - "description": "Metadata for this warning in 'key: value' format.", - "items": { - "type": "object", - "properties": { - "key": { - "type": "string", - "description": "A key for the warning data." - }, - "value": { - "type": "string", - "description": "A warning data value corresponding to the key." - } - } - } - }, - "message": { - "type": "string", - "description": "Optional human-readable details for this warning." - } - } - } - } - } - }, - "RouteList": { - "id": "RouteList", - "type": "object", - "description": "Contains a list of route resources.", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "array", - "description": "The route resources.", - "items": { - "$ref": "Route" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#routeList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "Scheduling": { - "id": "Scheduling", - "type": "object", - "description": "Scheduling options for an Instance.", - "properties": { - "automaticRestart": { - "type": "boolean", - "description": "Whether the Instance should be automatically restarted whenever it is terminated by Compute Engine (not terminated by user)." - }, - "onHostMaintenance": { - "type": "string", - "description": "How the instance should behave when the host machine undergoes maintenance that may temporarily impact instance performance.", - "enum": [ - "MIGRATE", - "TERMINATE" - ], - "enumDescriptions": [ - "", - "" - ] - } - } - }, - "SerialPortOutput": { - "id": "SerialPortOutput", - "type": "object", - "description": "An instance serial console output.", - "properties": { - "contents": { - "type": "string", - "description": "The contents of the console output." - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#serialPortOutput" - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - } - } - }, - "ServiceAccount": { - "id": "ServiceAccount", - "type": "object", - "description": "A service account.", - "properties": { - "email": { - "type": "string", - "description": "Email address of the service account." - }, - "scopes": { - "type": "array", - "description": "The list of scopes to be made available for this service account.", - "items": { - "type": "string" - } - } - } - }, - "Snapshot": { - "id": "Snapshot", - "type": "object", - "description": "A persistent disk snapshot resource.", - "properties": { - "creationTimestamp": { - "type": "string", - "description": "Creation timestamp in RFC3339 text format (output only)." - }, - "description": { - "type": "string", - "description": "An optional textual description of the resource; provided by the client when the resource is created." - }, - "diskSizeGb": { - "type": "string", - "description": "Size of the persistent disk snapshot, specified in GB (output only).", - "format": "int64" - }, - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only).", - "format": "uint64" - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#snapshot" - }, - "licenses": { - "type": "array", - "description": "Public visible licenses.", - "items": { - "type": "string" - } - }, - "name": { - "type": "string", - "description": "Name of the resource; provided by the client when the resource is created. The name must be 1-63 characters long, and comply with RFC1035.", - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?" - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - }, - "sourceDisk": { - "type": "string", - "description": "The source disk used to create this snapshot." - }, - "sourceDiskId": { - "type": "string", - "description": "The 'id' value of the disk used to create this snapshot. This value may be used to determine whether the snapshot was taken from the current or a previous instance of a given disk name." - }, - "status": { - "type": "string", - "description": "The status of the persistent disk snapshot (output only).", - "enum": [ - "CREATING", - "DELETING", - "FAILED", - "READY", - "UPLOADING" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "" - ] - }, - "storageBytes": { - "type": "string", - "description": "A size of the the storage used by the snapshot. As snapshots share storage this number is expected to change with snapshot creation/deletion.", - "format": "int64" - }, - "storageBytesStatus": { - "type": "string", - "description": "An indicator whether storageBytes is in a stable state, or it is being adjusted as a result of shared storage reallocation.", - "enum": [ - "UPDATING", - "UP_TO_DATE" - ], - "enumDescriptions": [ - "", - "" - ] - } - } - }, - "SnapshotList": { - "id": "SnapshotList", - "type": "object", - "description": "Contains a list of persistent disk snapshot resources.", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "array", - "description": "The persistent snapshot resources.", - "items": { - "$ref": "Snapshot" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#snapshotList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "Tags": { - "id": "Tags", - "type": "object", - "description": "A set of instance tags.", - "properties": { - "fingerprint": { - "type": "string", - "description": "Fingerprint of this resource. A hash of the tags stored in this object. This field is used optimistic locking. An up-to-date tags fingerprint must be provided in order to modify tags.", - "format": "byte" - }, - "items": { - "type": "array", - "description": "An array of tags. Each tag must be 1-63 characters long, and comply with RFC1035.", - "items": { - "type": "string" - } - } - } - }, - "TargetHttpProxy": { - "id": "TargetHttpProxy", - "type": "object", - "description": "A TargetHttpProxy resource. This resource defines an HTTP proxy.", - "properties": { - "creationTimestamp": { - "type": "string", - "description": "Creation timestamp in RFC3339 text format (output only)." - }, - "description": { - "type": "string", - "description": "An optional textual description of the resource; provided by the client when the resource is created." - }, - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only).", - "format": "uint64" - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#targetHttpProxy" - }, - "name": { - "type": "string", - "description": "Name of the resource; provided by the client when the resource is created. The name must be 1-63 characters long, and comply with RFC1035.", - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?" - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - }, - "urlMap": { - "type": "string", - "description": "URL to the UrlMap resource that defines the mapping from URL to the BackendService." - } - } - }, - "TargetHttpProxyList": { - "id": "TargetHttpProxyList", - "type": "object", - "description": "Contains a list of TargetHttpProxy resources.", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "array", - "description": "The TargetHttpProxy resources.", - "items": { - "$ref": "TargetHttpProxy" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#targetHttpProxyList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "TargetInstance": { - "id": "TargetInstance", - "type": "object", - "description": "A TargetInstance resource. This resource defines an endpoint VM that terminates traffic of certain protocols.", - "properties": { - "creationTimestamp": { - "type": "string", - "description": "Creation timestamp in RFC3339 text format (output only)." - }, - "description": { - "type": "string", - "description": "An optional textual description of the resource; provided by the client when the resource is created." - }, - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only).", - "format": "uint64" - }, - "instance": { - "type": "string", - "description": "The URL to the instance that terminates the relevant traffic." - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#targetInstance" - }, - "name": { - "type": "string", - "description": "Name of the resource; provided by the client when the resource is created. The name must be 1-63 characters long, and comply with RFC1035.", - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?" - }, - "natPolicy": { - "type": "string", - "description": "NAT option controlling how IPs are NAT'ed to the VM. Currently only NO_NAT (default value) is supported.", - "enum": [ - "NO_NAT" - ], - "enumDescriptions": [ - "" - ] - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - }, - "zone": { - "type": "string", - "description": "URL of the zone where the target instance resides (output only)." - } - } - }, - "TargetInstanceAggregatedList": { - "id": "TargetInstanceAggregatedList", - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "object", - "description": "A map of scoped target instance lists.", - "additionalProperties": { - "$ref": "TargetInstancesScopedList", - "description": "Name of the scope containing this set of target instances." - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#targetInstanceAggregatedList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "TargetInstanceList": { - "id": "TargetInstanceList", - "type": "object", - "description": "Contains a list of TargetInstance resources.", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "array", - "description": "The TargetInstance resources.", - "items": { - "$ref": "TargetInstance" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#targetInstanceList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "TargetInstancesScopedList": { - "id": "TargetInstancesScopedList", - "type": "object", - "properties": { - "targetInstances": { - "type": "array", - "description": "List of target instances contained in this scope.", - "items": { - "$ref": "TargetInstance" - } - }, - "warning": { - "type": "object", - "description": "Informational warning which replaces the list of addresses when the list is empty.", - "properties": { - "code": { - "type": "string", - "description": "The warning type identifier for this warning.", - "enum": [ - "DEPRECATED_RESOURCE_USED", - "DISK_SIZE_LARGER_THAN_IMAGE_SIZE", - "INJECTED_KERNELS_DEPRECATED", - "NEXT_HOP_ADDRESS_NOT_ASSIGNED", - "NEXT_HOP_CANNOT_IP_FORWARD", - "NEXT_HOP_INSTANCE_NOT_FOUND", - "NEXT_HOP_INSTANCE_NOT_ON_NETWORK", - "NEXT_HOP_NOT_RUNNING", - "NO_RESULTS_ON_PAGE", - "REQUIRED_TOS_AGREEMENT", - "RESOURCE_NOT_DELETED", - "UNREACHABLE" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "data": { - "type": "array", - "description": "Metadata for this warning in 'key: value' format.", - "items": { - "type": "object", - "properties": { - "key": { - "type": "string", - "description": "A key for the warning data." - }, - "value": { - "type": "string", - "description": "A warning data value corresponding to the key." - } - } - } - }, - "message": { - "type": "string", - "description": "Optional human-readable details for this warning." - } - } - } - } - }, - "TargetPool": { - "id": "TargetPool", - "type": "object", - "description": "A TargetPool resource. This resource defines a pool of VMs, associated HttpHealthCheck resources, and the fallback TargetPool.", - "properties": { - "backupPool": { - "type": "string", - "description": "This field is applicable only when the containing target pool is serving a forwarding rule as the primary pool, and its 'failoverRatio' field is properly set to a value between [0, 1].\n\n'backupPool' and 'failoverRatio' together define the fallback behavior of the primary target pool: if the ratio of the healthy VMs in the primary pool is at or below 'failoverRatio', traffic arriving at the load-balanced IP will be directed to the backup pool.\n\nIn case where 'failoverRatio' and 'backupPool' are not set, or all the VMs in the backup pool are unhealthy, the traffic will be directed back to the primary pool in the \"force\" mode, where traffic will be spread to the healthy VMs with the best effort, or to all VMs when no VM is healthy." - }, - "creationTimestamp": { - "type": "string", - "description": "Creation timestamp in RFC3339 text format (output only)." - }, - "description": { - "type": "string", - "description": "An optional textual description of the resource; provided by the client when the resource is created." - }, - "failoverRatio": { - "type": "number", - "description": "This field is applicable only when the containing target pool is serving a forwarding rule as the primary pool (i.e., not as a backup pool to some other target pool). The value of the field must be in [0, 1].\n\nIf set, 'backupPool' must also be set. They together define the fallback behavior of the primary target pool: if the ratio of the healthy VMs in the primary pool is at or below this number, traffic arriving at the load-balanced IP will be directed to the backup pool.\n\nIn case where 'failoverRatio' is not set or all the VMs in the backup pool are unhealthy, the traffic will be directed back to the primary pool in the \"force\" mode, where traffic will be spread to the healthy VMs with the best effort, or to all VMs when no VM is healthy.", - "format": "float" - }, - "healthChecks": { - "type": "array", - "description": "A list of URLs to the HttpHealthCheck resource. A member VM in this pool is considered healthy if and only if all specified health checks pass. An empty list means all member VMs will be considered healthy at all times.", - "items": { - "type": "string" - } - }, - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only).", - "format": "uint64" - }, - "instances": { - "type": "array", - "description": "A list of resource URLs to the member VMs serving this pool. They must live in zones contained in the same region as this pool.", - "items": { - "type": "string" - } - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#targetPool" - }, - "name": { - "type": "string", - "description": "Name of the resource; provided by the client when the resource is created. The name must be 1-63 characters long, and comply with RFC1035.", - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?" - }, - "region": { - "type": "string", - "description": "URL of the region where the target pool resides (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - }, - "sessionAffinity": { - "type": "string", - "description": "Sesssion affinity option, must be one of the following values: 'NONE': Connections from the same client IP may go to any VM in the pool; 'CLIENT_IP': Connections from the same client IP will go to the same VM in the pool while that VM remains healthy. 'CLIENT_IP_PROTO': Connections from the same client IP with the same IP protocol will go to the same VM in the pool while that VM remains healthy.", - "enum": [ - "CLIENT_IP", - "CLIENT_IP_PROTO", - "NONE" - ], - "enumDescriptions": [ - "", - "", - "" - ] - } - } - }, - "TargetPoolAggregatedList": { - "id": "TargetPoolAggregatedList", - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "object", - "description": "A map of scoped target pool lists.", - "additionalProperties": { - "$ref": "TargetPoolsScopedList", - "description": "Name of the scope containing this set of target pools." - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#targetPoolAggregatedList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "TargetPoolInstanceHealth": { - "id": "TargetPoolInstanceHealth", - "type": "object", - "properties": { - "healthStatus": { - "type": "array", - "items": { - "$ref": "HealthStatus" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#targetPoolInstanceHealth" - } - } - }, - "TargetPoolList": { - "id": "TargetPoolList", - "type": "object", - "description": "Contains a list of TargetPool resources.", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "array", - "description": "The TargetPool resources.", - "items": { - "$ref": "TargetPool" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#targetPoolList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "TargetPoolsAddHealthCheckRequest": { - "id": "TargetPoolsAddHealthCheckRequest", - "type": "object", - "properties": { - "healthChecks": { - "type": "array", - "description": "Health check URLs to be added to targetPool.", - "items": { - "$ref": "HealthCheckReference" - } - } - } - }, - "TargetPoolsAddInstanceRequest": { - "id": "TargetPoolsAddInstanceRequest", - "type": "object", - "properties": { - "instances": { - "type": "array", - "description": "URLs of the instances to be added to targetPool.", - "items": { - "$ref": "InstanceReference" - } - } - } - }, - "TargetPoolsRemoveHealthCheckRequest": { - "id": "TargetPoolsRemoveHealthCheckRequest", - "type": "object", - "properties": { - "healthChecks": { - "type": "array", - "description": "Health check URLs to be removed from targetPool.", - "items": { - "$ref": "HealthCheckReference" - } - } - } - }, - "TargetPoolsRemoveInstanceRequest": { - "id": "TargetPoolsRemoveInstanceRequest", - "type": "object", - "properties": { - "instances": { - "type": "array", - "description": "URLs of the instances to be removed from targetPool.", - "items": { - "$ref": "InstanceReference" - } - } - } - }, - "TargetPoolsScopedList": { - "id": "TargetPoolsScopedList", - "type": "object", - "properties": { - "targetPools": { - "type": "array", - "description": "List of target pools contained in this scope.", - "items": { - "$ref": "TargetPool" - } - }, - "warning": { - "type": "object", - "description": "Informational warning which replaces the list of addresses when the list is empty.", - "properties": { - "code": { - "type": "string", - "description": "The warning type identifier for this warning.", - "enum": [ - "DEPRECATED_RESOURCE_USED", - "DISK_SIZE_LARGER_THAN_IMAGE_SIZE", - "INJECTED_KERNELS_DEPRECATED", - "NEXT_HOP_ADDRESS_NOT_ASSIGNED", - "NEXT_HOP_CANNOT_IP_FORWARD", - "NEXT_HOP_INSTANCE_NOT_FOUND", - "NEXT_HOP_INSTANCE_NOT_ON_NETWORK", - "NEXT_HOP_NOT_RUNNING", - "NO_RESULTS_ON_PAGE", - "REQUIRED_TOS_AGREEMENT", - "RESOURCE_NOT_DELETED", - "UNREACHABLE" - ], - "enumDescriptions": [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "" - ] - }, - "data": { - "type": "array", - "description": "Metadata for this warning in 'key: value' format.", - "items": { - "type": "object", - "properties": { - "key": { - "type": "string", - "description": "A key for the warning data." - }, - "value": { - "type": "string", - "description": "A warning data value corresponding to the key." - } - } - } - }, - "message": { - "type": "string", - "description": "Optional human-readable details for this warning." - } - } - } - } - }, - "TargetReference": { - "id": "TargetReference", - "type": "object", - "properties": { - "target": { - "type": "string" - } - } - }, - "TestFailure": { - "id": "TestFailure", - "type": "object", - "properties": { - "actualService": { - "type": "string" - }, - "expectedService": { - "type": "string" - }, - "host": { - "type": "string" - }, - "path": { - "type": "string" - } - } - }, - "UrlMap": { - "id": "UrlMap", - "type": "object", - "description": "A UrlMap resource. This resource defines the mapping from URL to the BackendService resource, based on the \"longest-match\" of the URL's host and path.", - "properties": { - "creationTimestamp": { - "type": "string", - "description": "Creation timestamp in RFC3339 text format (output only)." - }, - "defaultService": { - "type": "string", - "description": "The URL of the BackendService resource if none of the hostRules match." - }, - "description": { - "type": "string", - "description": "An optional textual description of the resource; provided by the client when the resource is created." - }, - "fingerprint": { - "type": "string", - "description": "Fingerprint of this resource. A hash of the contents stored in this object. This field is used in optimistic locking. This field will be ignored when inserting a UrlMap. An up-to-date fingerprint must be provided in order to update the UrlMap.", - "format": "byte" - }, - "hostRules": { - "type": "array", - "description": "The list of HostRules to use against the URL.", - "items": { - "$ref": "HostRule" - } - }, - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only).", - "format": "uint64" - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#urlMap" - }, - "name": { - "type": "string", - "description": "Name of the resource; provided by the client when the resource is created. The name must be 1-63 characters long, and comply with RFC1035.", - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?" - }, - "pathMatchers": { - "type": "array", - "description": "The list of named PathMatchers to use against the URL.", - "items": { - "$ref": "PathMatcher" - } - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - }, - "tests": { - "type": "array", - "description": "The list of expected URL mappings. Request to update this UrlMap will succeed only all of the test cases pass.", - "items": { - "$ref": "UrlMapTest" - } - } - } - }, - "UrlMapList": { - "id": "UrlMapList", - "type": "object", - "description": "Contains a list of UrlMap resources.", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "array", - "description": "The UrlMap resources.", - "items": { - "$ref": "UrlMap" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#urlMapList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - }, - "UrlMapReference": { - "id": "UrlMapReference", - "type": "object", - "properties": { - "urlMap": { - "type": "string" - } - } - }, - "UrlMapTest": { - "id": "UrlMapTest", - "type": "object", - "description": "Message for the expected URL mappings.", - "properties": { - "description": { - "type": "string", - "description": "Description of this test case." - }, - "host": { - "type": "string", - "description": "Host portion of the URL." - }, - "path": { - "type": "string", - "description": "Path portion of the URL." - }, - "service": { - "type": "string", - "description": "Expected BackendService resource the given URL should be mapped to." - } - } - }, - "UrlMapValidationResult": { - "id": "UrlMapValidationResult", - "type": "object", - "description": "Message representing the validation result for a UrlMap.", - "properties": { - "loadErrors": { - "type": "array", - "items": { - "type": "string" - } - }, - "loadSucceeded": { - "type": "boolean", - "description": "Whether the given UrlMap can be successfully loaded. If false, 'loadErrors' indicates the reasons." - }, - "testFailures": { - "type": "array", - "items": { - "$ref": "TestFailure" - } - }, - "testPassed": { - "type": "boolean", - "description": "If successfully loaded, this field indicates whether the test passed. If false, 'testFailures's indicate the reason of failure." - } - } - }, - "UrlMapsValidateRequest": { - "id": "UrlMapsValidateRequest", - "type": "object", - "properties": { - "resource": { - "$ref": "UrlMap", - "description": "Content of the UrlMap to be validated." - } - } - }, - "UrlMapsValidateResponse": { - "id": "UrlMapsValidateResponse", - "type": "object", - "properties": { - "result": { - "$ref": "UrlMapValidationResult" - } - } - }, - "UsageExportLocation": { - "id": "UsageExportLocation", - "type": "object", - "description": "The location in Cloud Storage and naming method of the daily usage report. Contains bucket_name and report_name prefix.", - "properties": { - "bucketName": { - "type": "string", - "description": "The name of an existing bucket in Cloud Storage where the usage report object is stored. The Google Service Account is granted write access to this bucket. This is simply the bucket name, with no \"gs://\" or \"https://storage.googleapis.com/\" in front of it." - }, - "reportNamePrefix": { - "type": "string", - "description": "An optional prefix for the name of the usage report object stored in bucket_name. If not supplied, defaults to \"usage_\". The report is stored as a CSV file named _gce_.csv. where is the day of the usage according to Pacific Time. The prefix should conform to Cloud Storage object naming conventions." - } - } - }, - "Zone": { - "id": "Zone", - "type": "object", - "description": "A zone resource.", - "properties": { - "creationTimestamp": { - "type": "string", - "description": "Creation timestamp in RFC3339 text format (output only)." - }, - "deprecated": { - "$ref": "DeprecationStatus", - "description": "The deprecation status associated with this zone." - }, - "description": { - "type": "string", - "description": "Textual description of the resource." - }, - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only).", - "format": "uint64" - }, - "kind": { - "type": "string", - "description": "Type of the resource.", - "default": "compute#zone" - }, - "maintenanceWindows": { - "type": "array", - "description": "Scheduled maintenance windows for the zone. When the zone is in a maintenance window, all resources which reside in the zone will be unavailable.", - "items": { - "type": "object", - "properties": { - "beginTime": { - "type": "string", - "description": "Begin time of the maintenance window, in RFC 3339 format." - }, - "description": { - "type": "string", - "description": "Textual description of the maintenance window." - }, - "endTime": { - "type": "string", - "description": "End time of the maintenance window, in RFC 3339 format." - }, - "name": { - "type": "string", - "description": "Name of the maintenance window." - } - } - } - }, - "name": { - "type": "string", - "description": "Name of the resource." - }, - "region": { - "type": "string", - "description": "Full URL reference to the region which hosts the zone (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for the resource (output only)." - }, - "status": { - "type": "string", - "description": "Status of the zone. \"UP\" or \"DOWN\".", - "enum": [ - "DOWN", - "UP" - ], - "enumDescriptions": [ - "", - "" - ] - } - } - }, - "ZoneList": { - "id": "ZoneList", - "type": "object", - "description": "Contains a list of zone resources.", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier for the resource; defined by the server (output only)." - }, - "items": { - "type": "array", - "description": "The zone resources.", - "items": { - "$ref": "Zone" - } - }, - "kind": { - "type": "string", - "description": "Type of resource.", - "default": "compute#zoneList" - }, - "nextPageToken": { - "type": "string", - "description": "A token used to continue a truncated list request (output only)." - }, - "selfLink": { - "type": "string", - "description": "Server defined URL for this resource (output only)." - } - } - } - }, - "resources": { - "addresses": { - "methods": { - "aggregatedList": { - "id": "compute.addresses.aggregatedList", - "path": "{project}/aggregated/addresses", - "httpMethod": "GET", - "description": "Retrieves the list of addresses grouped by scope.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "AddressAggregatedList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "delete": { - "id": "compute.addresses.delete", - "path": "{project}/regions/{region}/addresses/{address}", - "httpMethod": "DELETE", - "description": "Deletes the specified address resource.", - "parameters": { - "address": { - "type": "string", - "description": "Name of the address resource to delete.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the region scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region", - "address" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "get": { - "id": "compute.addresses.get", - "path": "{project}/regions/{region}/addresses/{address}", - "httpMethod": "GET", - "description": "Returns the specified address resource.", - "parameters": { - "address": { - "type": "string", - "description": "Name of the address resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the region scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region", - "address" - ], - "response": { - "$ref": "Address" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "insert": { - "id": "compute.addresses.insert", - "path": "{project}/regions/{region}/addresses", - "httpMethod": "POST", - "description": "Creates an address resource in the specified project using the data included in the request.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the region scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region" - ], - "request": { - "$ref": "Address" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "list": { - "id": "compute.addresses.list", - "path": "{project}/regions/{region}/addresses", - "httpMethod": "GET", - "description": "Retrieves the list of address resources contained within the specified region.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the region scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region" - ], - "response": { - "$ref": "AddressList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - } - } - }, - "backendServices": { - "methods": { - "delete": { - "id": "compute.backendServices.delete", - "path": "{project}/global/backendServices/{backendService}", - "httpMethod": "DELETE", - "description": "Deletes the specified BackendService resource.", - "parameters": { - "backendService": { - "type": "string", - "description": "Name of the BackendService resource to delete.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "backendService" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "get": { - "id": "compute.backendServices.get", - "path": "{project}/global/backendServices/{backendService}", - "httpMethod": "GET", - "description": "Returns the specified BackendService resource.", - "parameters": { - "backendService": { - "type": "string", - "description": "Name of the BackendService resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "backendService" - ], - "response": { - "$ref": "BackendService" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "getHealth": { - "id": "compute.backendServices.getHealth", - "path": "{project}/global/backendServices/{backendService}/getHealth", - "httpMethod": "POST", - "description": "Gets the most recent health check results for this BackendService.", - "parameters": { - "backendService": { - "type": "string", - "description": "Name of the BackendService resource to which the queried instance belongs.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "backendService" - ], - "request": { - "$ref": "ResourceGroupReference" - }, - "response": { - "$ref": "BackendServiceGroupHealth" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "insert": { - "id": "compute.backendServices.insert", - "path": "{project}/global/backendServices", - "httpMethod": "POST", - "description": "Creates a BackendService resource in the specified project using the data included in the request.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "request": { - "$ref": "BackendService" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "list": { - "id": "compute.backendServices.list", - "path": "{project}/global/backendServices", - "httpMethod": "GET", - "description": "Retrieves the list of BackendService resources available to the specified project.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "BackendServiceList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "patch": { - "id": "compute.backendServices.patch", - "path": "{project}/global/backendServices/{backendService}", - "httpMethod": "PATCH", - "description": "Update the entire content of the BackendService resource. This method supports patch semantics.", - "parameters": { - "backendService": { - "type": "string", - "description": "Name of the BackendService resource to update.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "backendService" - ], - "request": { - "$ref": "BackendService" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "update": { - "id": "compute.backendServices.update", - "path": "{project}/global/backendServices/{backendService}", - "httpMethod": "PUT", - "description": "Update the entire content of the BackendService resource.", - "parameters": { - "backendService": { - "type": "string", - "description": "Name of the BackendService resource to update.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "backendService" - ], - "request": { - "$ref": "BackendService" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - } - } - }, - "diskTypes": { - "methods": { - "aggregatedList": { - "id": "compute.diskTypes.aggregatedList", - "path": "{project}/aggregated/diskTypes", - "httpMethod": "GET", - "description": "Retrieves the list of disk type resources grouped by scope.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "DiskTypeAggregatedList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "get": { - "id": "compute.diskTypes.get", - "path": "{project}/zones/{zone}/diskTypes/{diskType}", - "httpMethod": "GET", - "description": "Returns the specified disk type resource.", - "parameters": { - "diskType": { - "type": "string", - "description": "Name of the disk type resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone", - "diskType" - ], - "response": { - "$ref": "DiskType" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "list": { - "id": "compute.diskTypes.list", - "path": "{project}/zones/{zone}/diskTypes", - "httpMethod": "GET", - "description": "Retrieves the list of disk type resources available to the specified project.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone" - ], - "response": { - "$ref": "DiskTypeList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - } - } - }, - "disks": { - "methods": { - "aggregatedList": { - "id": "compute.disks.aggregatedList", - "path": "{project}/aggregated/disks", - "httpMethod": "GET", - "description": "Retrieves the list of disks grouped by scope.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "DiskAggregatedList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "createSnapshot": { - "id": "compute.disks.createSnapshot", - "path": "{project}/zones/{zone}/disks/{disk}/createSnapshot", - "httpMethod": "POST", - "parameters": { - "disk": { - "type": "string", - "description": "Name of the persistent disk resource to snapshot.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone", - "disk" - ], - "request": { - "$ref": "Snapshot" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "delete": { - "id": "compute.disks.delete", - "path": "{project}/zones/{zone}/disks/{disk}", - "httpMethod": "DELETE", - "description": "Deletes the specified persistent disk resource.", - "parameters": { - "disk": { - "type": "string", - "description": "Name of the persistent disk resource to delete.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone", - "disk" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "get": { - "id": "compute.disks.get", - "path": "{project}/zones/{zone}/disks/{disk}", - "httpMethod": "GET", - "description": "Returns the specified persistent disk resource.", - "parameters": { - "disk": { - "type": "string", - "description": "Name of the persistent disk resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone", - "disk" - ], - "response": { - "$ref": "Disk" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "insert": { - "id": "compute.disks.insert", - "path": "{project}/zones/{zone}/disks", - "httpMethod": "POST", - "description": "Creates a persistent disk resource in the specified project using the data included in the request.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "sourceImage": { - "type": "string", - "description": "Optional. Source image to restore onto a disk.", - "location": "query" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone" - ], - "request": { - "$ref": "Disk" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "list": { - "id": "compute.disks.list", - "path": "{project}/zones/{zone}/disks", - "httpMethod": "GET", - "description": "Retrieves the list of persistent disk resources contained within the specified zone.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone" - ], - "response": { - "$ref": "DiskList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - } - } - }, - "firewalls": { - "methods": { - "delete": { - "id": "compute.firewalls.delete", - "path": "{project}/global/firewalls/{firewall}", - "httpMethod": "DELETE", - "description": "Deletes the specified firewall resource.", - "parameters": { - "firewall": { - "type": "string", - "description": "Name of the firewall resource to delete.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "firewall" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "get": { - "id": "compute.firewalls.get", - "path": "{project}/global/firewalls/{firewall}", - "httpMethod": "GET", - "description": "Returns the specified firewall resource.", - "parameters": { - "firewall": { - "type": "string", - "description": "Name of the firewall resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "firewall" - ], - "response": { - "$ref": "Firewall" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "insert": { - "id": "compute.firewalls.insert", - "path": "{project}/global/firewalls", - "httpMethod": "POST", - "description": "Creates a firewall resource in the specified project using the data included in the request.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "request": { - "$ref": "Firewall" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "list": { - "id": "compute.firewalls.list", - "path": "{project}/global/firewalls", - "httpMethod": "GET", - "description": "Retrieves the list of firewall resources available to the specified project.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "FirewallList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "patch": { - "id": "compute.firewalls.patch", - "path": "{project}/global/firewalls/{firewall}", - "httpMethod": "PATCH", - "description": "Updates the specified firewall resource with the data included in the request. This method supports patch semantics.", - "parameters": { - "firewall": { - "type": "string", - "description": "Name of the firewall resource to update.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "firewall" - ], - "request": { - "$ref": "Firewall" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "update": { - "id": "compute.firewalls.update", - "path": "{project}/global/firewalls/{firewall}", - "httpMethod": "PUT", - "description": "Updates the specified firewall resource with the data included in the request.", - "parameters": { - "firewall": { - "type": "string", - "description": "Name of the firewall resource to update.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "firewall" - ], - "request": { - "$ref": "Firewall" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - } - } - }, - "forwardingRules": { - "methods": { - "aggregatedList": { - "id": "compute.forwardingRules.aggregatedList", - "path": "{project}/aggregated/forwardingRules", - "httpMethod": "GET", - "description": "Retrieves the list of forwarding rules grouped by scope.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "ForwardingRuleAggregatedList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "delete": { - "id": "compute.forwardingRules.delete", - "path": "{project}/regions/{region}/forwardingRules/{forwardingRule}", - "httpMethod": "DELETE", - "description": "Deletes the specified ForwardingRule resource.", - "parameters": { - "forwardingRule": { - "type": "string", - "description": "Name of the ForwardingRule resource to delete.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the region scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region", - "forwardingRule" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "get": { - "id": "compute.forwardingRules.get", - "path": "{project}/regions/{region}/forwardingRules/{forwardingRule}", - "httpMethod": "GET", - "description": "Returns the specified ForwardingRule resource.", - "parameters": { - "forwardingRule": { - "type": "string", - "description": "Name of the ForwardingRule resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the region scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region", - "forwardingRule" - ], - "response": { - "$ref": "ForwardingRule" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "insert": { - "id": "compute.forwardingRules.insert", - "path": "{project}/regions/{region}/forwardingRules", - "httpMethod": "POST", - "description": "Creates a ForwardingRule resource in the specified project and region using the data included in the request.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the region scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region" - ], - "request": { - "$ref": "ForwardingRule" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "list": { - "id": "compute.forwardingRules.list", - "path": "{project}/regions/{region}/forwardingRules", - "httpMethod": "GET", - "description": "Retrieves the list of ForwardingRule resources available to the specified project and region.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the region scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region" - ], - "response": { - "$ref": "ForwardingRuleList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "setTarget": { - "id": "compute.forwardingRules.setTarget", - "path": "{project}/regions/{region}/forwardingRules/{forwardingRule}/setTarget", - "httpMethod": "POST", - "description": "Changes target url for forwarding rule.", - "parameters": { - "forwardingRule": { - "type": "string", - "description": "Name of the ForwardingRule resource in which target is to be set.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the region scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region", - "forwardingRule" - ], - "request": { - "$ref": "TargetReference" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - } - } - }, - "globalAddresses": { - "methods": { - "delete": { - "id": "compute.globalAddresses.delete", - "path": "{project}/global/addresses/{address}", - "httpMethod": "DELETE", - "description": "Deletes the specified address resource.", - "parameters": { - "address": { - "type": "string", - "description": "Name of the address resource to delete.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "address" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "get": { - "id": "compute.globalAddresses.get", - "path": "{project}/global/addresses/{address}", - "httpMethod": "GET", - "description": "Returns the specified address resource.", - "parameters": { - "address": { - "type": "string", - "description": "Name of the address resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "address" - ], - "response": { - "$ref": "Address" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "insert": { - "id": "compute.globalAddresses.insert", - "path": "{project}/global/addresses", - "httpMethod": "POST", - "description": "Creates an address resource in the specified project using the data included in the request.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "request": { - "$ref": "Address" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "list": { - "id": "compute.globalAddresses.list", - "path": "{project}/global/addresses", - "httpMethod": "GET", - "description": "Retrieves the list of global address resources.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "AddressList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - } - } - }, - "globalForwardingRules": { - "methods": { - "delete": { - "id": "compute.globalForwardingRules.delete", - "path": "{project}/global/forwardingRules/{forwardingRule}", - "httpMethod": "DELETE", - "description": "Deletes the specified ForwardingRule resource.", - "parameters": { - "forwardingRule": { - "type": "string", - "description": "Name of the ForwardingRule resource to delete.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "forwardingRule" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "get": { - "id": "compute.globalForwardingRules.get", - "path": "{project}/global/forwardingRules/{forwardingRule}", - "httpMethod": "GET", - "description": "Returns the specified ForwardingRule resource.", - "parameters": { - "forwardingRule": { - "type": "string", - "description": "Name of the ForwardingRule resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "forwardingRule" - ], - "response": { - "$ref": "ForwardingRule" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "insert": { - "id": "compute.globalForwardingRules.insert", - "path": "{project}/global/forwardingRules", - "httpMethod": "POST", - "description": "Creates a ForwardingRule resource in the specified project and region using the data included in the request.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "request": { - "$ref": "ForwardingRule" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "list": { - "id": "compute.globalForwardingRules.list", - "path": "{project}/global/forwardingRules", - "httpMethod": "GET", - "description": "Retrieves the list of ForwardingRule resources available to the specified project.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "ForwardingRuleList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "setTarget": { - "id": "compute.globalForwardingRules.setTarget", - "path": "{project}/global/forwardingRules/{forwardingRule}/setTarget", - "httpMethod": "POST", - "description": "Changes target url for forwarding rule.", - "parameters": { - "forwardingRule": { - "type": "string", - "description": "Name of the ForwardingRule resource in which target is to be set.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "forwardingRule" - ], - "request": { - "$ref": "TargetReference" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - } - } - }, - "globalOperations": { - "methods": { - "aggregatedList": { - "id": "compute.globalOperations.aggregatedList", - "path": "{project}/aggregated/operations", - "httpMethod": "GET", - "description": "Retrieves the list of all operations grouped by scope.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "OperationAggregatedList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "delete": { - "id": "compute.globalOperations.delete", - "path": "{project}/global/operations/{operation}", - "httpMethod": "DELETE", - "description": "Deletes the specified operation resource.", - "parameters": { - "operation": { - "type": "string", - "description": "Name of the operation resource to delete.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "operation" - ], - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "get": { - "id": "compute.globalOperations.get", - "path": "{project}/global/operations/{operation}", - "httpMethod": "GET", - "description": "Retrieves the specified operation resource.", - "parameters": { - "operation": { - "type": "string", - "description": "Name of the operation resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "operation" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "list": { - "id": "compute.globalOperations.list", - "path": "{project}/global/operations", - "httpMethod": "GET", - "description": "Retrieves the list of operation resources contained within the specified project.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "OperationList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - } - } - }, - "httpHealthChecks": { - "methods": { - "delete": { - "id": "compute.httpHealthChecks.delete", - "path": "{project}/global/httpHealthChecks/{httpHealthCheck}", - "httpMethod": "DELETE", - "description": "Deletes the specified HttpHealthCheck resource.", - "parameters": { - "httpHealthCheck": { - "type": "string", - "description": "Name of the HttpHealthCheck resource to delete.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "httpHealthCheck" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "get": { - "id": "compute.httpHealthChecks.get", - "path": "{project}/global/httpHealthChecks/{httpHealthCheck}", - "httpMethod": "GET", - "description": "Returns the specified HttpHealthCheck resource.", - "parameters": { - "httpHealthCheck": { - "type": "string", - "description": "Name of the HttpHealthCheck resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "httpHealthCheck" - ], - "response": { - "$ref": "HttpHealthCheck" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "insert": { - "id": "compute.httpHealthChecks.insert", - "path": "{project}/global/httpHealthChecks", - "httpMethod": "POST", - "description": "Creates a HttpHealthCheck resource in the specified project using the data included in the request.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "request": { - "$ref": "HttpHealthCheck" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "list": { - "id": "compute.httpHealthChecks.list", - "path": "{project}/global/httpHealthChecks", - "httpMethod": "GET", - "description": "Retrieves the list of HttpHealthCheck resources available to the specified project.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "HttpHealthCheckList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "patch": { - "id": "compute.httpHealthChecks.patch", - "path": "{project}/global/httpHealthChecks/{httpHealthCheck}", - "httpMethod": "PATCH", - "description": "Updates a HttpHealthCheck resource in the specified project using the data included in the request. This method supports patch semantics.", - "parameters": { - "httpHealthCheck": { - "type": "string", - "description": "Name of the HttpHealthCheck resource to update.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "httpHealthCheck" - ], - "request": { - "$ref": "HttpHealthCheck" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "update": { - "id": "compute.httpHealthChecks.update", - "path": "{project}/global/httpHealthChecks/{httpHealthCheck}", - "httpMethod": "PUT", - "description": "Updates a HttpHealthCheck resource in the specified project using the data included in the request.", - "parameters": { - "httpHealthCheck": { - "type": "string", - "description": "Name of the HttpHealthCheck resource to update.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "httpHealthCheck" - ], - "request": { - "$ref": "HttpHealthCheck" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - } - } - }, - "images": { - "methods": { - "delete": { - "id": "compute.images.delete", - "path": "{project}/global/images/{image}", - "httpMethod": "DELETE", - "description": "Deletes the specified image resource.", - "parameters": { - "image": { - "type": "string", - "description": "Name of the image resource to delete.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "image" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "deprecate": { - "id": "compute.images.deprecate", - "path": "{project}/global/images/{image}/deprecate", - "httpMethod": "POST", - "description": "Sets the deprecation status of an image. If no message body is given, clears the deprecation status instead.", - "parameters": { - "image": { - "type": "string", - "description": "Image name.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "image" - ], - "request": { - "$ref": "DeprecationStatus" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "get": { - "id": "compute.images.get", - "path": "{project}/global/images/{image}", - "httpMethod": "GET", - "description": "Returns the specified image resource.", - "parameters": { - "image": { - "type": "string", - "description": "Name of the image resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "image" - ], - "response": { - "$ref": "Image" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "insert": { - "id": "compute.images.insert", - "path": "{project}/global/images", - "httpMethod": "POST", - "description": "Creates an image resource in the specified project using the data included in the request.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "request": { - "$ref": "Image" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_only", - "https://www.googleapis.com/auth/devstorage.read_write" - ] - }, - "list": { - "id": "compute.images.list", - "path": "{project}/global/images", - "httpMethod": "GET", - "description": "Retrieves the list of image resources available to the specified project.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "ImageList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - } - } - }, - "instanceTemplates": { - "methods": { - "delete": { - "id": "compute.instanceTemplates.delete", - "path": "{project}/global/instanceTemplates/{instanceTemplate}", - "httpMethod": "DELETE", - "description": "Deletes the specified instance template resource.", - "parameters": { - "instanceTemplate": { - "type": "string", - "description": "Name of the instance template resource to delete.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "instanceTemplate" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "get": { - "id": "compute.instanceTemplates.get", - "path": "{project}/global/instanceTemplates/{instanceTemplate}", - "httpMethod": "GET", - "description": "Returns the specified instance template resource.", - "parameters": { - "instanceTemplate": { - "type": "string", - "description": "Name of the instance template resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "instanceTemplate" - ], - "response": { - "$ref": "InstanceTemplate" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "insert": { - "id": "compute.instanceTemplates.insert", - "path": "{project}/global/instanceTemplates", - "httpMethod": "POST", - "description": "Creates an instance template resource in the specified project using the data included in the request.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "request": { - "$ref": "InstanceTemplate" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "list": { - "id": "compute.instanceTemplates.list", - "path": "{project}/global/instanceTemplates", - "httpMethod": "GET", - "description": "Retrieves the list of instance template resources contained within the specified project.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "InstanceTemplateList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - } - } - }, - "instances": { - "methods": { - "addAccessConfig": { - "id": "compute.instances.addAccessConfig", - "path": "{project}/zones/{zone}/instances/{instance}/addAccessConfig", - "httpMethod": "POST", - "description": "Adds an access config to an instance's network interface.", - "parameters": { - "instance": { - "type": "string", - "description": "Instance name.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "networkInterface": { - "type": "string", - "description": "Network interface name.", - "required": true, - "location": "query" - }, - "project": { - "type": "string", - "description": "Project name.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone", - "instance", - "networkInterface" - ], - "request": { - "$ref": "AccessConfig" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "aggregatedList": { - "id": "compute.instances.aggregatedList", - "path": "{project}/aggregated/instances", - "httpMethod": "GET", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "InstanceAggregatedList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "attachDisk": { - "id": "compute.instances.attachDisk", - "path": "{project}/zones/{zone}/instances/{instance}/attachDisk", - "httpMethod": "POST", - "description": "Attaches a disk resource to an instance.", - "parameters": { - "instance": { - "type": "string", - "description": "Instance name.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Project name.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone", - "instance" - ], - "request": { - "$ref": "AttachedDisk" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "delete": { - "id": "compute.instances.delete", - "path": "{project}/zones/{zone}/instances/{instance}", - "httpMethod": "DELETE", - "description": "Deletes the specified instance resource.", - "parameters": { - "instance": { - "type": "string", - "description": "Name of the instance resource to delete.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone", - "instance" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "deleteAccessConfig": { - "id": "compute.instances.deleteAccessConfig", - "path": "{project}/zones/{zone}/instances/{instance}/deleteAccessConfig", - "httpMethod": "POST", - "description": "Deletes an access config from an instance's network interface.", - "parameters": { - "accessConfig": { - "type": "string", - "description": "Access config name.", - "required": true, - "location": "query" - }, - "instance": { - "type": "string", - "description": "Instance name.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "networkInterface": { - "type": "string", - "description": "Network interface name.", - "required": true, - "location": "query" - }, - "project": { - "type": "string", - "description": "Project name.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone", - "instance", - "accessConfig", - "networkInterface" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "detachDisk": { - "id": "compute.instances.detachDisk", - "path": "{project}/zones/{zone}/instances/{instance}/detachDisk", - "httpMethod": "POST", - "description": "Detaches a disk from an instance.", - "parameters": { - "deviceName": { - "type": "string", - "description": "Disk device name to detach.", - "required": true, - "pattern": "\\w[\\w.-]{0,254}", - "location": "query" - }, - "instance": { - "type": "string", - "description": "Instance name.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Project name.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone", - "instance", - "deviceName" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "get": { - "id": "compute.instances.get", - "path": "{project}/zones/{zone}/instances/{instance}", - "httpMethod": "GET", - "description": "Returns the specified instance resource.", - "parameters": { - "instance": { - "type": "string", - "description": "Name of the instance resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone", - "instance" - ], - "response": { - "$ref": "Instance" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "getSerialPortOutput": { - "id": "compute.instances.getSerialPortOutput", - "path": "{project}/zones/{zone}/instances/{instance}/serialPort", - "httpMethod": "GET", - "description": "Returns the specified instance's serial port output.", - "parameters": { - "instance": { - "type": "string", - "description": "Name of the instance scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone", - "instance" - ], - "response": { - "$ref": "SerialPortOutput" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "insert": { - "id": "compute.instances.insert", - "path": "{project}/zones/{zone}/instances", - "httpMethod": "POST", - "description": "Creates an instance resource in the specified project using the data included in the request.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone" - ], - "request": { - "$ref": "Instance" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "list": { - "id": "compute.instances.list", - "path": "{project}/zones/{zone}/instances", - "httpMethod": "GET", - "description": "Retrieves the list of instance resources contained within the specified zone.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone" - ], - "response": { - "$ref": "InstanceList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "reset": { - "id": "compute.instances.reset", - "path": "{project}/zones/{zone}/instances/{instance}/reset", - "httpMethod": "POST", - "description": "Performs a hard reset on the instance.", - "parameters": { - "instance": { - "type": "string", - "description": "Name of the instance scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone", - "instance" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "setDiskAutoDelete": { - "id": "compute.instances.setDiskAutoDelete", - "path": "{project}/zones/{zone}/instances/{instance}/setDiskAutoDelete", - "httpMethod": "POST", - "description": "Sets the auto-delete flag for a disk attached to an instance", - "parameters": { - "autoDelete": { - "type": "boolean", - "description": "Whether to auto-delete the disk when the instance is deleted.", - "required": true, - "location": "query" - }, - "deviceName": { - "type": "string", - "description": "Disk device name to modify.", - "required": true, - "pattern": "\\w[\\w.-]{0,254}", - "location": "query" - }, - "instance": { - "type": "string", - "description": "Instance name.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Project name.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone", - "instance", - "autoDelete", - "deviceName" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "setMetadata": { - "id": "compute.instances.setMetadata", - "path": "{project}/zones/{zone}/instances/{instance}/setMetadata", - "httpMethod": "POST", - "description": "Sets metadata for the specified instance to the data included in the request.", - "parameters": { - "instance": { - "type": "string", - "description": "Name of the instance scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone", - "instance" - ], - "request": { - "$ref": "Metadata" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "setScheduling": { - "id": "compute.instances.setScheduling", - "path": "{project}/zones/{zone}/instances/{instance}/setScheduling", - "httpMethod": "POST", - "description": "Sets an instance's scheduling options.", - "parameters": { - "instance": { - "type": "string", - "description": "Instance name.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Project name.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone", - "instance" - ], - "request": { - "$ref": "Scheduling" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "setTags": { - "id": "compute.instances.setTags", - "path": "{project}/zones/{zone}/instances/{instance}/setTags", - "httpMethod": "POST", - "description": "Sets tags for the specified instance to the data included in the request.", - "parameters": { - "instance": { - "type": "string", - "description": "Name of the instance scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone", - "instance" - ], - "request": { - "$ref": "Tags" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - } - } - }, - "licenses": { - "methods": { - "get": { - "id": "compute.licenses.get", - "path": "{project}/global/licenses/{license}", - "httpMethod": "GET", - "description": "Returns the specified license resource.", - "parameters": { - "license": { - "type": "string", - "description": "Name of the license resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "license" - ], - "response": { - "$ref": "License" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - } - } - }, - "machineTypes": { - "methods": { - "aggregatedList": { - "id": "compute.machineTypes.aggregatedList", - "path": "{project}/aggregated/machineTypes", - "httpMethod": "GET", - "description": "Retrieves the list of machine type resources grouped by scope.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "MachineTypeAggregatedList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "get": { - "id": "compute.machineTypes.get", - "path": "{project}/zones/{zone}/machineTypes/{machineType}", - "httpMethod": "GET", - "description": "Returns the specified machine type resource.", - "parameters": { - "machineType": { - "type": "string", - "description": "Name of the machine type resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone", - "machineType" - ], - "response": { - "$ref": "MachineType" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "list": { - "id": "compute.machineTypes.list", - "path": "{project}/zones/{zone}/machineTypes", - "httpMethod": "GET", - "description": "Retrieves the list of machine type resources available to the specified project.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone" - ], - "response": { - "$ref": "MachineTypeList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - } - } - }, - "networks": { - "methods": { - "delete": { - "id": "compute.networks.delete", - "path": "{project}/global/networks/{network}", - "httpMethod": "DELETE", - "description": "Deletes the specified network resource.", - "parameters": { - "network": { - "type": "string", - "description": "Name of the network resource to delete.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "network" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "get": { - "id": "compute.networks.get", - "path": "{project}/global/networks/{network}", - "httpMethod": "GET", - "description": "Returns the specified network resource.", - "parameters": { - "network": { - "type": "string", - "description": "Name of the network resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "network" - ], - "response": { - "$ref": "Network" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "insert": { - "id": "compute.networks.insert", - "path": "{project}/global/networks", - "httpMethod": "POST", - "description": "Creates a network resource in the specified project using the data included in the request.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "request": { - "$ref": "Network" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "list": { - "id": "compute.networks.list", - "path": "{project}/global/networks", - "httpMethod": "GET", - "description": "Retrieves the list of network resources available to the specified project.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "NetworkList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - } - } - }, - "projects": { - "methods": { - "get": { - "id": "compute.projects.get", - "path": "{project}", - "httpMethod": "GET", - "description": "Returns the specified project resource.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project resource to retrieve.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "Project" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "setCommonInstanceMetadata": { - "id": "compute.projects.setCommonInstanceMetadata", - "path": "{project}/setCommonInstanceMetadata", - "httpMethod": "POST", - "description": "Sets metadata common to all instances within the specified project using the data included in the request.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "request": { - "$ref": "Metadata" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "setUsageExportBucket": { - "id": "compute.projects.setUsageExportBucket", - "path": "{project}/setUsageExportBucket", - "httpMethod": "POST", - "description": "Sets usage export location", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "request": { - "$ref": "UsageExportLocation" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/devstorage.full_control", - "https://www.googleapis.com/auth/devstorage.read_only", - "https://www.googleapis.com/auth/devstorage.read_write" - ] - } - } - }, - "regionOperations": { - "methods": { - "delete": { - "id": "compute.regionOperations.delete", - "path": "{project}/regions/{region}/operations/{operation}", - "httpMethod": "DELETE", - "description": "Deletes the specified region-specific operation resource.", - "parameters": { - "operation": { - "type": "string", - "description": "Name of the operation resource to delete.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the region scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region", - "operation" - ], - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "get": { - "id": "compute.regionOperations.get", - "path": "{project}/regions/{region}/operations/{operation}", - "httpMethod": "GET", - "description": "Retrieves the specified region-specific operation resource.", - "parameters": { - "operation": { - "type": "string", - "description": "Name of the operation resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region", - "operation" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "list": { - "id": "compute.regionOperations.list", - "path": "{project}/regions/{region}/operations", - "httpMethod": "GET", - "description": "Retrieves the list of operation resources contained within the specified region.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the region scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region" - ], - "response": { - "$ref": "OperationList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - } - } - }, - "regions": { - "methods": { - "get": { - "id": "compute.regions.get", - "path": "{project}/regions/{region}", - "httpMethod": "GET", - "description": "Returns the specified region resource.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the region resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region" - ], - "response": { - "$ref": "Region" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "list": { - "id": "compute.regions.list", - "path": "{project}/regions", - "httpMethod": "GET", - "description": "Retrieves the list of region resources available to the specified project.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "RegionList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - } - } - }, - "routes": { - "methods": { - "delete": { - "id": "compute.routes.delete", - "path": "{project}/global/routes/{route}", - "httpMethod": "DELETE", - "description": "Deletes the specified route resource.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "route": { - "type": "string", - "description": "Name of the route resource to delete.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "route" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "get": { - "id": "compute.routes.get", - "path": "{project}/global/routes/{route}", - "httpMethod": "GET", - "description": "Returns the specified route resource.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "route": { - "type": "string", - "description": "Name of the route resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "route" - ], - "response": { - "$ref": "Route" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "insert": { - "id": "compute.routes.insert", - "path": "{project}/global/routes", - "httpMethod": "POST", - "description": "Creates a route resource in the specified project using the data included in the request.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "request": { - "$ref": "Route" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "list": { - "id": "compute.routes.list", - "path": "{project}/global/routes", - "httpMethod": "GET", - "description": "Retrieves the list of route resources available to the specified project.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "RouteList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - } - } - }, - "snapshots": { - "methods": { - "delete": { - "id": "compute.snapshots.delete", - "path": "{project}/global/snapshots/{snapshot}", - "httpMethod": "DELETE", - "description": "Deletes the specified persistent disk snapshot resource.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "snapshot": { - "type": "string", - "description": "Name of the persistent disk snapshot resource to delete.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "snapshot" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "get": { - "id": "compute.snapshots.get", - "path": "{project}/global/snapshots/{snapshot}", - "httpMethod": "GET", - "description": "Returns the specified persistent disk snapshot resource.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "snapshot": { - "type": "string", - "description": "Name of the persistent disk snapshot resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "snapshot" - ], - "response": { - "$ref": "Snapshot" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "list": { - "id": "compute.snapshots.list", - "path": "{project}/global/snapshots", - "httpMethod": "GET", - "description": "Retrieves the list of persistent disk snapshot resources contained within the specified project.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "SnapshotList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - } - } - }, - "targetHttpProxies": { - "methods": { - "delete": { - "id": "compute.targetHttpProxies.delete", - "path": "{project}/global/targetHttpProxies/{targetHttpProxy}", - "httpMethod": "DELETE", - "description": "Deletes the specified TargetHttpProxy resource.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "targetHttpProxy": { - "type": "string", - "description": "Name of the TargetHttpProxy resource to delete.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "targetHttpProxy" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "get": { - "id": "compute.targetHttpProxies.get", - "path": "{project}/global/targetHttpProxies/{targetHttpProxy}", - "httpMethod": "GET", - "description": "Returns the specified TargetHttpProxy resource.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "targetHttpProxy": { - "type": "string", - "description": "Name of the TargetHttpProxy resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "targetHttpProxy" - ], - "response": { - "$ref": "TargetHttpProxy" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "insert": { - "id": "compute.targetHttpProxies.insert", - "path": "{project}/global/targetHttpProxies", - "httpMethod": "POST", - "description": "Creates a TargetHttpProxy resource in the specified project using the data included in the request.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "request": { - "$ref": "TargetHttpProxy" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "list": { - "id": "compute.targetHttpProxies.list", - "path": "{project}/global/targetHttpProxies", - "httpMethod": "GET", - "description": "Retrieves the list of TargetHttpProxy resources available to the specified project.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "TargetHttpProxyList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "setUrlMap": { - "id": "compute.targetHttpProxies.setUrlMap", - "path": "{project}/targetHttpProxies/{targetHttpProxy}/setUrlMap", - "httpMethod": "POST", - "description": "Changes the URL map for TargetHttpProxy.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "targetHttpProxy": { - "type": "string", - "description": "Name of the TargetHttpProxy resource whose URL map is to be set.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "targetHttpProxy" - ], - "request": { - "$ref": "UrlMapReference" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - } - } - }, - "targetInstances": { - "methods": { - "aggregatedList": { - "id": "compute.targetInstances.aggregatedList", - "path": "{project}/aggregated/targetInstances", - "httpMethod": "GET", - "description": "Retrieves the list of target instances grouped by scope.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "TargetInstanceAggregatedList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "delete": { - "id": "compute.targetInstances.delete", - "path": "{project}/zones/{zone}/targetInstances/{targetInstance}", - "httpMethod": "DELETE", - "description": "Deletes the specified TargetInstance resource.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "targetInstance": { - "type": "string", - "description": "Name of the TargetInstance resource to delete.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone", - "targetInstance" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "get": { - "id": "compute.targetInstances.get", - "path": "{project}/zones/{zone}/targetInstances/{targetInstance}", - "httpMethod": "GET", - "description": "Returns the specified TargetInstance resource.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "targetInstance": { - "type": "string", - "description": "Name of the TargetInstance resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone", - "targetInstance" - ], - "response": { - "$ref": "TargetInstance" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "insert": { - "id": "compute.targetInstances.insert", - "path": "{project}/zones/{zone}/targetInstances", - "httpMethod": "POST", - "description": "Creates a TargetInstance resource in the specified project and zone using the data included in the request.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone" - ], - "request": { - "$ref": "TargetInstance" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "list": { - "id": "compute.targetInstances.list", - "path": "{project}/zones/{zone}/targetInstances", - "httpMethod": "GET", - "description": "Retrieves the list of TargetInstance resources available to the specified project and zone.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone" - ], - "response": { - "$ref": "TargetInstanceList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - } - } - }, - "targetPools": { - "methods": { - "addHealthCheck": { - "id": "compute.targetPools.addHealthCheck", - "path": "{project}/regions/{region}/targetPools/{targetPool}/addHealthCheck", - "httpMethod": "POST", - "description": "Adds health check URL to targetPool.", - "parameters": { - "project": { - "type": "string", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the region scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "targetPool": { - "type": "string", - "description": "Name of the TargetPool resource to which health_check_url is to be added.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region", - "targetPool" - ], - "request": { - "$ref": "TargetPoolsAddHealthCheckRequest" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "addInstance": { - "id": "compute.targetPools.addInstance", - "path": "{project}/regions/{region}/targetPools/{targetPool}/addInstance", - "httpMethod": "POST", - "description": "Adds instance url to targetPool.", - "parameters": { - "project": { - "type": "string", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the region scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "targetPool": { - "type": "string", - "description": "Name of the TargetPool resource to which instance_url is to be added.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region", - "targetPool" - ], - "request": { - "$ref": "TargetPoolsAddInstanceRequest" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "aggregatedList": { - "id": "compute.targetPools.aggregatedList", - "path": "{project}/aggregated/targetPools", - "httpMethod": "GET", - "description": "Retrieves the list of target pools grouped by scope.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "TargetPoolAggregatedList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "delete": { - "id": "compute.targetPools.delete", - "path": "{project}/regions/{region}/targetPools/{targetPool}", - "httpMethod": "DELETE", - "description": "Deletes the specified TargetPool resource.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the region scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "targetPool": { - "type": "string", - "description": "Name of the TargetPool resource to delete.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region", - "targetPool" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "get": { - "id": "compute.targetPools.get", - "path": "{project}/regions/{region}/targetPools/{targetPool}", - "httpMethod": "GET", - "description": "Returns the specified TargetPool resource.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the region scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "targetPool": { - "type": "string", - "description": "Name of the TargetPool resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region", - "targetPool" - ], - "response": { - "$ref": "TargetPool" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "getHealth": { - "id": "compute.targetPools.getHealth", - "path": "{project}/regions/{region}/targetPools/{targetPool}/getHealth", - "httpMethod": "POST", - "description": "Gets the most recent health check results for each IP for the given instance that is referenced by given TargetPool.", - "parameters": { - "project": { - "type": "string", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the region scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "targetPool": { - "type": "string", - "description": "Name of the TargetPool resource to which the queried instance belongs.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region", - "targetPool" - ], - "request": { - "$ref": "InstanceReference" - }, - "response": { - "$ref": "TargetPoolInstanceHealth" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "insert": { - "id": "compute.targetPools.insert", - "path": "{project}/regions/{region}/targetPools", - "httpMethod": "POST", - "description": "Creates a TargetPool resource in the specified project and region using the data included in the request.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the region scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region" - ], - "request": { - "$ref": "TargetPool" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "list": { - "id": "compute.targetPools.list", - "path": "{project}/regions/{region}/targetPools", - "httpMethod": "GET", - "description": "Retrieves the list of TargetPool resources available to the specified project and region.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the region scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region" - ], - "response": { - "$ref": "TargetPoolList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "removeHealthCheck": { - "id": "compute.targetPools.removeHealthCheck", - "path": "{project}/regions/{region}/targetPools/{targetPool}/removeHealthCheck", - "httpMethod": "POST", - "description": "Removes health check URL from targetPool.", - "parameters": { - "project": { - "type": "string", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the region scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "targetPool": { - "type": "string", - "description": "Name of the TargetPool resource to which health_check_url is to be removed.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region", - "targetPool" - ], - "request": { - "$ref": "TargetPoolsRemoveHealthCheckRequest" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "removeInstance": { - "id": "compute.targetPools.removeInstance", - "path": "{project}/regions/{region}/targetPools/{targetPool}/removeInstance", - "httpMethod": "POST", - "description": "Removes instance URL from targetPool.", - "parameters": { - "project": { - "type": "string", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the region scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "targetPool": { - "type": "string", - "description": "Name of the TargetPool resource to which instance_url is to be removed.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region", - "targetPool" - ], - "request": { - "$ref": "TargetPoolsRemoveInstanceRequest" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "setBackup": { - "id": "compute.targetPools.setBackup", - "path": "{project}/regions/{region}/targetPools/{targetPool}/setBackup", - "httpMethod": "POST", - "description": "Changes backup pool configurations.", - "parameters": { - "failoverRatio": { - "type": "number", - "description": "New failoverRatio value for the containing target pool.", - "format": "float", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "region": { - "type": "string", - "description": "Name of the region scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "targetPool": { - "type": "string", - "description": "Name of the TargetPool resource for which the backup is to be set.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "region", - "targetPool" - ], - "request": { - "$ref": "TargetReference" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - } - } - }, - "urlMaps": { - "methods": { - "delete": { - "id": "compute.urlMaps.delete", - "path": "{project}/global/urlMaps/{urlMap}", - "httpMethod": "DELETE", - "description": "Deletes the specified UrlMap resource.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "urlMap": { - "type": "string", - "description": "Name of the UrlMap resource to delete.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "urlMap" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "get": { - "id": "compute.urlMaps.get", - "path": "{project}/global/urlMaps/{urlMap}", - "httpMethod": "GET", - "description": "Returns the specified UrlMap resource.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "urlMap": { - "type": "string", - "description": "Name of the UrlMap resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "urlMap" - ], - "response": { - "$ref": "UrlMap" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "insert": { - "id": "compute.urlMaps.insert", - "path": "{project}/global/urlMaps", - "httpMethod": "POST", - "description": "Creates a UrlMap resource in the specified project using the data included in the request.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "request": { - "$ref": "UrlMap" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "list": { - "id": "compute.urlMaps.list", - "path": "{project}/global/urlMaps", - "httpMethod": "GET", - "description": "Retrieves the list of UrlMap resources available to the specified project.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "UrlMapList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "patch": { - "id": "compute.urlMaps.patch", - "path": "{project}/global/urlMaps/{urlMap}", - "httpMethod": "PATCH", - "description": "Update the entire content of the UrlMap resource. This method supports patch semantics.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "urlMap": { - "type": "string", - "description": "Name of the UrlMap resource to update.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "urlMap" - ], - "request": { - "$ref": "UrlMap" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "update": { - "id": "compute.urlMaps.update", - "path": "{project}/global/urlMaps/{urlMap}", - "httpMethod": "PUT", - "description": "Update the entire content of the UrlMap resource.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "urlMap": { - "type": "string", - "description": "Name of the UrlMap resource to update.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "urlMap" - ], - "request": { - "$ref": "UrlMap" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "validate": { - "id": "compute.urlMaps.validate", - "path": "{project}/global/urlMaps/{urlMap}/validate", - "httpMethod": "POST", - "description": "Run static validation for the UrlMap. In particular, the tests of the provided UrlMap will be run. Calling this method does NOT create the UrlMap.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "urlMap": { - "type": "string", - "description": "Name of the UrlMap resource to be validated as.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "urlMap" - ], - "request": { - "$ref": "UrlMapsValidateRequest" - }, - "response": { - "$ref": "UrlMapsValidateResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - } - } - }, - "zoneOperations": { - "methods": { - "delete": { - "id": "compute.zoneOperations.delete", - "path": "{project}/zones/{zone}/operations/{operation}", - "httpMethod": "DELETE", - "description": "Deletes the specified zone-specific operation resource.", - "parameters": { - "operation": { - "type": "string", - "description": "Name of the operation resource to delete.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone", - "operation" - ], - "scopes": [ - "https://www.googleapis.com/auth/compute" - ] - }, - "get": { - "id": "compute.zoneOperations.get", - "path": "{project}/zones/{zone}/operations/{operation}", - "httpMethod": "GET", - "description": "Retrieves the specified zone-specific operation resource.", - "parameters": { - "operation": { - "type": "string", - "description": "Name of the operation resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone", - "operation" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "list": { - "id": "compute.zoneOperations.list", - "path": "{project}/zones/{zone}/operations", - "httpMethod": "GET", - "description": "Retrieves the list of operation resources contained within the specified zone.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone scoping this request.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone" - ], - "response": { - "$ref": "OperationList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - } - } - }, - "zones": { - "methods": { - "get": { - "id": "compute.zones.get", - "path": "{project}/zones/{zone}", - "httpMethod": "GET", - "description": "Returns the specified zone resource.", - "parameters": { - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - }, - "zone": { - "type": "string", - "description": "Name of the zone resource to return.", - "required": true, - "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - "location": "path" - } - }, - "parameterOrder": [ - "project", - "zone" - ], - "response": { - "$ref": "Zone" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - }, - "list": { - "id": "compute.zones.list", - "path": "{project}/zones", - "httpMethod": "GET", - "description": "Retrieves the list of zone resources available to the specified project.", - "parameters": { - "filter": { - "type": "string", - "description": "Optional. Filter expression for filtering listed resources.", - "location": "query" - }, - "maxResults": { - "type": "integer", - "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - "default": "500", - "format": "uint32", - "minimum": "0", - "maximum": "500", - "location": "query" - }, - "pageToken": { - "type": "string", - "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - "location": "query" - }, - "project": { - "type": "string", - "description": "Name of the project scoping this request.", - "required": true, - "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - "location": "path" - } - }, - "parameterOrder": [ - "project" - ], - "response": { - "$ref": "ZoneList" - }, - "scopes": [ - "https://www.googleapis.com/auth/compute", - "https://www.googleapis.com/auth/compute.readonly" - ] - } - } - } - } -} diff --git a/Godeps/_workspace/src/code.google.com/p/google-api-go-client/compute/v1/v1/compute-gen.go b/Godeps/_workspace/src/code.google.com/p/google-api-go-client/compute/v1/v1/compute-gen.go deleted file mode 100644 index 7d193b56b844..000000000000 --- a/Godeps/_workspace/src/code.google.com/p/google-api-go-client/compute/v1/v1/compute-gen.go +++ /dev/null @@ -1,16952 +0,0 @@ -// Package compute provides access to the Compute Engine API. -// -// See https://developers.google.com/compute/docs/reference/latest/ -// -// Usage example: -// -// import "code.google.com/p/google-api-go-client/compute/v1" -// ... -// computeService, err := compute.New(oauthHttpClient) -package compute - -import ( - "bytes" - "code.google.com/p/google-api-go-client/googleapi" - "encoding/json" - "errors" - "fmt" - "io" - "net/http" - "net/url" - "strconv" - "strings" -) - -// Always reference these packages, just in case the auto-generated code -// below doesn't. -var _ = bytes.NewBuffer -var _ = strconv.Itoa -var _ = fmt.Sprintf -var _ = json.NewDecoder -var _ = io.Copy -var _ = url.Parse -var _ = googleapi.Version -var _ = errors.New -var _ = strings.Replace - -const apiId = "compute:v1" -const apiName = "compute" -const apiVersion = "v1" -const basePath = "https://www.googleapis.com/compute/v1/projects/" - -// OAuth2 scopes used by this API. -const ( - // View and manage your Google Compute Engine resources - ComputeScope = "https://www.googleapis.com/auth/compute" - - // View your Google Compute Engine resources - ComputeReadonlyScope = "https://www.googleapis.com/auth/compute.readonly" - - // Manage your data and permissions in Google Cloud Storage - DevstorageFull_controlScope = "https://www.googleapis.com/auth/devstorage.full_control" - - // View your data in Google Cloud Storage - DevstorageRead_onlyScope = "https://www.googleapis.com/auth/devstorage.read_only" - - // Manage your data in Google Cloud Storage - DevstorageRead_writeScope = "https://www.googleapis.com/auth/devstorage.read_write" -) - -func New(client *http.Client) (*Service, error) { - if client == nil { - return nil, errors.New("client is nil") - } - s := &Service{client: client, BasePath: basePath} - s.Addresses = NewAddressesService(s) - s.BackendServices = NewBackendServicesService(s) - s.DiskTypes = NewDiskTypesService(s) - s.Disks = NewDisksService(s) - s.Firewalls = NewFirewallsService(s) - s.ForwardingRules = NewForwardingRulesService(s) - s.GlobalAddresses = NewGlobalAddressesService(s) - s.GlobalForwardingRules = NewGlobalForwardingRulesService(s) - s.GlobalOperations = NewGlobalOperationsService(s) - s.HttpHealthChecks = NewHttpHealthChecksService(s) - s.Images = NewImagesService(s) - s.InstanceTemplates = NewInstanceTemplatesService(s) - s.Instances = NewInstancesService(s) - s.Licenses = NewLicensesService(s) - s.MachineTypes = NewMachineTypesService(s) - s.Networks = NewNetworksService(s) - s.Projects = NewProjectsService(s) - s.RegionOperations = NewRegionOperationsService(s) - s.Regions = NewRegionsService(s) - s.Routes = NewRoutesService(s) - s.Snapshots = NewSnapshotsService(s) - s.TargetHttpProxies = NewTargetHttpProxiesService(s) - s.TargetInstances = NewTargetInstancesService(s) - s.TargetPools = NewTargetPoolsService(s) - s.UrlMaps = NewUrlMapsService(s) - s.ZoneOperations = NewZoneOperationsService(s) - s.Zones = NewZonesService(s) - return s, nil -} - -type Service struct { - client *http.Client - BasePath string // API endpoint base URL - - Addresses *AddressesService - - BackendServices *BackendServicesService - - DiskTypes *DiskTypesService - - Disks *DisksService - - Firewalls *FirewallsService - - ForwardingRules *ForwardingRulesService - - GlobalAddresses *GlobalAddressesService - - GlobalForwardingRules *GlobalForwardingRulesService - - GlobalOperations *GlobalOperationsService - - HttpHealthChecks *HttpHealthChecksService - - Images *ImagesService - - InstanceTemplates *InstanceTemplatesService - - Instances *InstancesService - - Licenses *LicensesService - - MachineTypes *MachineTypesService - - Networks *NetworksService - - Projects *ProjectsService - - RegionOperations *RegionOperationsService - - Regions *RegionsService - - Routes *RoutesService - - Snapshots *SnapshotsService - - TargetHttpProxies *TargetHttpProxiesService - - TargetInstances *TargetInstancesService - - TargetPools *TargetPoolsService - - UrlMaps *UrlMapsService - - ZoneOperations *ZoneOperationsService - - Zones *ZonesService -} - -func NewAddressesService(s *Service) *AddressesService { - rs := &AddressesService{s: s} - return rs -} - -type AddressesService struct { - s *Service -} - -func NewBackendServicesService(s *Service) *BackendServicesService { - rs := &BackendServicesService{s: s} - return rs -} - -type BackendServicesService struct { - s *Service -} - -func NewDiskTypesService(s *Service) *DiskTypesService { - rs := &DiskTypesService{s: s} - return rs -} - -type DiskTypesService struct { - s *Service -} - -func NewDisksService(s *Service) *DisksService { - rs := &DisksService{s: s} - return rs -} - -type DisksService struct { - s *Service -} - -func NewFirewallsService(s *Service) *FirewallsService { - rs := &FirewallsService{s: s} - return rs -} - -type FirewallsService struct { - s *Service -} - -func NewForwardingRulesService(s *Service) *ForwardingRulesService { - rs := &ForwardingRulesService{s: s} - return rs -} - -type ForwardingRulesService struct { - s *Service -} - -func NewGlobalAddressesService(s *Service) *GlobalAddressesService { - rs := &GlobalAddressesService{s: s} - return rs -} - -type GlobalAddressesService struct { - s *Service -} - -func NewGlobalForwardingRulesService(s *Service) *GlobalForwardingRulesService { - rs := &GlobalForwardingRulesService{s: s} - return rs -} - -type GlobalForwardingRulesService struct { - s *Service -} - -func NewGlobalOperationsService(s *Service) *GlobalOperationsService { - rs := &GlobalOperationsService{s: s} - return rs -} - -type GlobalOperationsService struct { - s *Service -} - -func NewHttpHealthChecksService(s *Service) *HttpHealthChecksService { - rs := &HttpHealthChecksService{s: s} - return rs -} - -type HttpHealthChecksService struct { - s *Service -} - -func NewImagesService(s *Service) *ImagesService { - rs := &ImagesService{s: s} - return rs -} - -type ImagesService struct { - s *Service -} - -func NewInstanceTemplatesService(s *Service) *InstanceTemplatesService { - rs := &InstanceTemplatesService{s: s} - return rs -} - -type InstanceTemplatesService struct { - s *Service -} - -func NewInstancesService(s *Service) *InstancesService { - rs := &InstancesService{s: s} - return rs -} - -type InstancesService struct { - s *Service -} - -func NewLicensesService(s *Service) *LicensesService { - rs := &LicensesService{s: s} - return rs -} - -type LicensesService struct { - s *Service -} - -func NewMachineTypesService(s *Service) *MachineTypesService { - rs := &MachineTypesService{s: s} - return rs -} - -type MachineTypesService struct { - s *Service -} - -func NewNetworksService(s *Service) *NetworksService { - rs := &NetworksService{s: s} - return rs -} - -type NetworksService struct { - s *Service -} - -func NewProjectsService(s *Service) *ProjectsService { - rs := &ProjectsService{s: s} - return rs -} - -type ProjectsService struct { - s *Service -} - -func NewRegionOperationsService(s *Service) *RegionOperationsService { - rs := &RegionOperationsService{s: s} - return rs -} - -type RegionOperationsService struct { - s *Service -} - -func NewRegionsService(s *Service) *RegionsService { - rs := &RegionsService{s: s} - return rs -} - -type RegionsService struct { - s *Service -} - -func NewRoutesService(s *Service) *RoutesService { - rs := &RoutesService{s: s} - return rs -} - -type RoutesService struct { - s *Service -} - -func NewSnapshotsService(s *Service) *SnapshotsService { - rs := &SnapshotsService{s: s} - return rs -} - -type SnapshotsService struct { - s *Service -} - -func NewTargetHttpProxiesService(s *Service) *TargetHttpProxiesService { - rs := &TargetHttpProxiesService{s: s} - return rs -} - -type TargetHttpProxiesService struct { - s *Service -} - -func NewTargetInstancesService(s *Service) *TargetInstancesService { - rs := &TargetInstancesService{s: s} - return rs -} - -type TargetInstancesService struct { - s *Service -} - -func NewTargetPoolsService(s *Service) *TargetPoolsService { - rs := &TargetPoolsService{s: s} - return rs -} - -type TargetPoolsService struct { - s *Service -} - -func NewUrlMapsService(s *Service) *UrlMapsService { - rs := &UrlMapsService{s: s} - return rs -} - -type UrlMapsService struct { - s *Service -} - -func NewZoneOperationsService(s *Service) *ZoneOperationsService { - rs := &ZoneOperationsService{s: s} - return rs -} - -type ZoneOperationsService struct { - s *Service -} - -func NewZonesService(s *Service) *ZonesService { - rs := &ZonesService{s: s} - return rs -} - -type ZonesService struct { - s *Service -} - -type AccessConfig struct { - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // Name: Name of this access configuration. - Name string `json:"name,omitempty"` - - // NatIP: An external IP address associated with this instance. Specify - // an unused static IP address available to the project. If not - // specified, the external IP will be drawn from a shared ephemeral - // pool. - NatIP string `json:"natIP,omitempty"` - - // Type: Type of configuration. Must be set to "ONE_TO_ONE_NAT". This - // configures port-for-port NAT to the internet. - Type string `json:"type,omitempty"` -} - -type Address struct { - // Address: The IP address represented by this resource. - Address string `json:"address,omitempty"` - - // CreationTimestamp: Creation timestamp in RFC3339 text format (output - // only). - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // Description: An optional textual description of the resource; - // provided by the client when the resource is created. - Description string `json:"description,omitempty"` - - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id uint64 `json:"id,omitempty,string"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // Name: Name of the resource; provided by the client when the resource - // is created. The name must be 1-63 characters long, and comply with - // RFC1035. - Name string `json:"name,omitempty"` - - // Region: URL of the region where the regional address resides (output - // only). This field is not applicable to global addresses. - Region string `json:"region,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` - - // Status: The status of the address (output only). - Status string `json:"status,omitempty"` - - // Users: The resources that are using this address resource. - Users []string `json:"users,omitempty"` -} - -type AddressAggregatedList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: A map of scoped address lists. - Items map[string]AddressesScopedList `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type AddressList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: The address resources. - Items []*Address `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type AddressesScopedList struct { - // Addresses: List of addresses contained in this scope. - Addresses []*Address `json:"addresses,omitempty"` - - // Warning: Informational warning which replaces the list of addresses - // when the list is empty. - Warning *AddressesScopedListWarning `json:"warning,omitempty"` -} - -type AddressesScopedListWarning struct { - // Code: The warning type identifier for this warning. - Code string `json:"code,omitempty"` - - // Data: Metadata for this warning in 'key: value' format. - Data []*AddressesScopedListWarningData `json:"data,omitempty"` - - // Message: Optional human-readable details for this warning. - Message string `json:"message,omitempty"` -} - -type AddressesScopedListWarningData struct { - // Key: A key for the warning data. - Key string `json:"key,omitempty"` - - // Value: A warning data value corresponding to the key. - Value string `json:"value,omitempty"` -} - -type AttachedDisk struct { - // AutoDelete: Whether the disk will be auto-deleted when the instance - // is deleted (but not when the disk is detached from the instance). - AutoDelete bool `json:"autoDelete,omitempty"` - - // Boot: Indicates that this is a boot disk. VM will use the first - // partition of the disk for its root filesystem. - Boot bool `json:"boot,omitempty"` - - // DeviceName: Persistent disk only; must be unique within the instance - // when specified. This represents a unique device name that is - // reflected into the /dev/ tree of a Linux operating system running - // within the instance. If not specified, a default will be chosen by - // the system. - DeviceName string `json:"deviceName,omitempty"` - - // Index: A zero-based index to assign to this disk, where 0 is reserved - // for the boot disk. If not specified, the server will choose an - // appropriate value (output only). - Index int64 `json:"index,omitempty"` - - // InitializeParams: Initialization parameters. - InitializeParams *AttachedDiskInitializeParams `json:"initializeParams,omitempty"` - - Interface string `json:"interface,omitempty"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // Licenses: Public visible licenses. - Licenses []string `json:"licenses,omitempty"` - - // Mode: The mode in which to attach this disk, either "READ_WRITE" or - // "READ_ONLY". - Mode string `json:"mode,omitempty"` - - // Source: Persistent disk only; the URL of the persistent disk - // resource. - Source string `json:"source,omitempty"` - - // Type: Type of the disk, either "SCRATCH" or "PERSISTENT". Note that - // persistent disks must be created before you can specify them here. - Type string `json:"type,omitempty"` -} - -type AttachedDiskInitializeParams struct { - // DiskName: Name of the disk (when not provided defaults to the name of - // the instance). - DiskName string `json:"diskName,omitempty"` - - // DiskSizeGb: Size of the disk in base-2 GB. - DiskSizeGb int64 `json:"diskSizeGb,omitempty,string"` - - // DiskType: URL of the disk type resource describing which disk type to - // use to create the disk; provided by the client when the disk is - // created. - DiskType string `json:"diskType,omitempty"` - - // SourceImage: The source image used to create this disk. - SourceImage string `json:"sourceImage,omitempty"` -} - -type Backend struct { - // BalancingMode: The balancing mode of this backend, default is - // UTILIZATION. - BalancingMode string `json:"balancingMode,omitempty"` - - // CapacityScaler: The multiplier (a value between 0 and 1e6) of the max - // capacity (CPU or RPS, depending on 'balancingMode') the group should - // serve up to. 0 means the group is totally drained. Default value is - // 1. Valid range is [0, 1e6]. - CapacityScaler float64 `json:"capacityScaler,omitempty"` - - // Description: An optional textual description of the resource, which - // is provided by the client when the resource is created. - Description string `json:"description,omitempty"` - - // Group: URL of a zonal Cloud Resource View resource. This resource - // view defines the list of instances that serve traffic. Member virtual - // machine instances from each resource view must live in the same zone - // as the resource view itself. No two backends in a backend service are - // allowed to use same Resource View resource. - Group string `json:"group,omitempty"` - - // MaxRate: The max RPS of the group. Can be used with either balancing - // mode, but required if RATE mode. For RATE mode, either maxRate or - // maxRatePerInstance must be set. - MaxRate int64 `json:"maxRate,omitempty"` - - // MaxRatePerInstance: The max RPS that a single backed instance can - // handle. This is used to calculate the capacity of the group. Can be - // used in either balancing mode. For RATE mode, either maxRate or - // maxRatePerInstance must be set. - MaxRatePerInstance float64 `json:"maxRatePerInstance,omitempty"` - - // MaxUtilization: Used when 'balancingMode' is UTILIZATION. This ratio - // defines the CPU utilization target for the group. The default is 0.8. - // Valid range is [0, 1]. - MaxUtilization float64 `json:"maxUtilization,omitempty"` -} - -type BackendService struct { - // Backends: The list of backends that serve this BackendService. - Backends []*Backend `json:"backends,omitempty"` - - // CreationTimestamp: Creation timestamp in RFC3339 text format (output - // only). - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // Description: An optional textual description of the resource; - // provided by the client when the resource is created. - Description string `json:"description,omitempty"` - - // Fingerprint: Fingerprint of this resource. A hash of the contents - // stored in this object. This field is used in optimistic locking. This - // field will be ignored when inserting a BackendService. An up-to-date - // fingerprint must be provided in order to update the BackendService. - Fingerprint string `json:"fingerprint,omitempty"` - - // HealthChecks: The list of URLs to the HttpHealthCheck resource for - // health checking this BackendService. Currently at most one health - // check can be specified, and a health check is required. - HealthChecks []string `json:"healthChecks,omitempty"` - - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id uint64 `json:"id,omitempty,string"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // Name: Name of the resource; provided by the client when the resource - // is created. The name must be 1-63 characters long, and comply with - // RFC1035. - Name string `json:"name,omitempty"` - - // Port: Deprecated in favor of port_name. The TCP port to connect on - // the backend. The default value is 80. - Port int64 `json:"port,omitempty"` - - // PortName: Name of backend port. The same name should appear in the - // resource views referenced by this service. Required. - PortName string `json:"portName,omitempty"` - - Protocol string `json:"protocol,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` - - // TimeoutSec: How many seconds to wait for the backend before - // considering it a failed request. Default is 30 seconds. - TimeoutSec int64 `json:"timeoutSec,omitempty"` -} - -type BackendServiceGroupHealth struct { - HealthStatus []*HealthStatus `json:"healthStatus,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` -} - -type BackendServiceList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: The BackendService resources. - Items []*BackendService `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type DeprecationStatus struct { - // Deleted: An optional RFC3339 timestamp on or after which the - // deprecation state of this resource will be changed to DELETED. - Deleted string `json:"deleted,omitempty"` - - // Deprecated: An optional RFC3339 timestamp on or after which the - // deprecation state of this resource will be changed to DEPRECATED. - Deprecated string `json:"deprecated,omitempty"` - - // Obsolete: An optional RFC3339 timestamp on or after which the - // deprecation state of this resource will be changed to OBSOLETE. - Obsolete string `json:"obsolete,omitempty"` - - // Replacement: A URL of the suggested replacement for the deprecated - // resource. The deprecated resource and its replacement must be - // resources of the same kind. - Replacement string `json:"replacement,omitempty"` - - // State: The deprecation state. Can be "DEPRECATED", "OBSOLETE", or - // "DELETED". Operations which create a new resource using a - // "DEPRECATED" resource will return successfully, but with a warning - // indicating the deprecated resource and recommending its replacement. - // New uses of "OBSOLETE" or "DELETED" resources will result in an - // error. - State string `json:"state,omitempty"` -} - -type Disk struct { - // CreationTimestamp: Creation timestamp in RFC3339 text format (output - // only). - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // Description: An optional textual description of the resource; - // provided by the client when the resource is created. - Description string `json:"description,omitempty"` - - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id uint64 `json:"id,omitempty,string"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // Licenses: Public visible licenses. - Licenses []string `json:"licenses,omitempty"` - - // Name: Name of the resource; provided by the client when the resource - // is created. The name must be 1-63 characters long, and comply with - // RFC1035. - Name string `json:"name,omitempty"` - - // Options: Internal use only. - Options string `json:"options,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` - - // SizeGb: Size of the persistent disk, specified in GB. This parameter - // is optional when creating a disk from a disk image or a snapshot, - // otherwise it is required. - SizeGb int64 `json:"sizeGb,omitempty,string"` - - // SourceImage: The source image used to create this disk. - SourceImage string `json:"sourceImage,omitempty"` - - // SourceImageId: The 'id' value of the image used to create this disk. - // This value may be used to determine whether the disk was created from - // the current or a previous instance of a given image. - SourceImageId string `json:"sourceImageId,omitempty"` - - // SourceSnapshot: The source snapshot used to create this disk. - SourceSnapshot string `json:"sourceSnapshot,omitempty"` - - // SourceSnapshotId: The 'id' value of the snapshot used to create this - // disk. This value may be used to determine whether the disk was - // created from the current or a previous instance of a given disk - // snapshot. - SourceSnapshotId string `json:"sourceSnapshotId,omitempty"` - - // Status: The status of disk creation (output only). - Status string `json:"status,omitempty"` - - // Type: URL of the disk type resource describing which disk type to use - // to create the disk; provided by the client when the disk is created. - Type string `json:"type,omitempty"` - - // Zone: URL of the zone where the disk resides (output only). - Zone string `json:"zone,omitempty"` -} - -type DiskAggregatedList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: A map of scoped disk lists. - Items map[string]DisksScopedList `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type DiskList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: The persistent disk resources. - Items []*Disk `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type DiskType struct { - // CreationTimestamp: Creation timestamp in RFC3339 text format (output - // only). - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // DefaultDiskSizeGb: Server defined default disk size in gb (output - // only). - DefaultDiskSizeGb int64 `json:"defaultDiskSizeGb,omitempty,string"` - - // Deprecated: The deprecation status associated with this disk type. - Deprecated *DeprecationStatus `json:"deprecated,omitempty"` - - // Description: An optional textual description of the resource. - Description string `json:"description,omitempty"` - - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id uint64 `json:"id,omitempty,string"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // Name: Name of the resource. - Name string `json:"name,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` - - // ValidDiskSize: An optional textual descroption of the valid disk - // size, e.g., "10GB-10TB". - ValidDiskSize string `json:"validDiskSize,omitempty"` - - // Zone: Url of the zone where the disk type resides (output only). - Zone string `json:"zone,omitempty"` -} - -type DiskTypeAggregatedList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: A map of scoped disk type lists. - Items map[string]DiskTypesScopedList `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type DiskTypeList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: The disk type resources. - Items []*DiskType `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type DiskTypesScopedList struct { - // DiskTypes: List of disk types contained in this scope. - DiskTypes []*DiskType `json:"diskTypes,omitempty"` - - // Warning: Informational warning which replaces the list of disk types - // when the list is empty. - Warning *DiskTypesScopedListWarning `json:"warning,omitempty"` -} - -type DiskTypesScopedListWarning struct { - // Code: The warning type identifier for this warning. - Code string `json:"code,omitempty"` - - // Data: Metadata for this warning in 'key: value' format. - Data []*DiskTypesScopedListWarningData `json:"data,omitempty"` - - // Message: Optional human-readable details for this warning. - Message string `json:"message,omitempty"` -} - -type DiskTypesScopedListWarningData struct { - // Key: A key for the warning data. - Key string `json:"key,omitempty"` - - // Value: A warning data value corresponding to the key. - Value string `json:"value,omitempty"` -} - -type DisksScopedList struct { - // Disks: List of disks contained in this scope. - Disks []*Disk `json:"disks,omitempty"` - - // Warning: Informational warning which replaces the list of disks when - // the list is empty. - Warning *DisksScopedListWarning `json:"warning,omitempty"` -} - -type DisksScopedListWarning struct { - // Code: The warning type identifier for this warning. - Code string `json:"code,omitempty"` - - // Data: Metadata for this warning in 'key: value' format. - Data []*DisksScopedListWarningData `json:"data,omitempty"` - - // Message: Optional human-readable details for this warning. - Message string `json:"message,omitempty"` -} - -type DisksScopedListWarningData struct { - // Key: A key for the warning data. - Key string `json:"key,omitempty"` - - // Value: A warning data value corresponding to the key. - Value string `json:"value,omitempty"` -} - -type Firewall struct { - // Allowed: The list of rules specified by this firewall. Each rule - // specifies a protocol and port-range tuple that describes a permitted - // connection. - Allowed []*FirewallAllowed `json:"allowed,omitempty"` - - // CreationTimestamp: Creation timestamp in RFC3339 text format (output - // only). - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // Description: An optional textual description of the resource; - // provided by the client when the resource is created. - Description string `json:"description,omitempty"` - - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id uint64 `json:"id,omitempty,string"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // Name: Name of the resource; provided by the client when the resource - // is created. The name must be 1-63 characters long, and comply with - // RFC1035. - Name string `json:"name,omitempty"` - - // Network: URL of the network to which this firewall is applied; - // provided by the client when the firewall is created. - Network string `json:"network,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` - - // SourceRanges: A list of IP address blocks expressed in CIDR format - // which this rule applies to. One or both of sourceRanges and - // sourceTags may be set; an inbound connection is allowed if either the - // range or the tag of the source matches. - SourceRanges []string `json:"sourceRanges,omitempty"` - - // SourceTags: A list of instance tags which this rule applies to. One - // or both of sourceRanges and sourceTags may be set; an inbound - // connection is allowed if either the range or the tag of the source - // matches. - SourceTags []string `json:"sourceTags,omitempty"` - - // TargetTags: A list of instance tags indicating sets of instances - // located on network which may make network connections as specified in - // allowed. If no targetTags are specified, the firewall rule applies to - // all instances on the specified network. - TargetTags []string `json:"targetTags,omitempty"` -} - -type FirewallAllowed struct { - // IPProtocol: Required; this is the IP protocol that is allowed for - // this rule. This can either be one of the following well known - // protocol strings ["tcp", "udp", "icmp", "esp", "ah", "sctp"], or the - // IP protocol number. - IPProtocol string `json:"IPProtocol,omitempty"` - - // Ports: An optional list of ports which are allowed. It is an error to - // specify this for any protocol that isn't UDP or TCP. Each entry must - // be either an integer or a range. If not specified, connections - // through any port are allowed. - // - // Example inputs include: ["22"], - // ["80","443"] and ["12345-12349"]. - Ports []string `json:"ports,omitempty"` -} - -type FirewallList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: The firewall resources. - Items []*Firewall `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type ForwardingRule struct { - // IPAddress: Value of the reserved IP address that this forwarding rule - // is serving on behalf of. For global forwarding rules, the address - // must be a global IP; for regional forwarding rules, the address must - // live in the same region as the forwarding rule. If left empty - // (default value), an ephemeral IP from the same scope (global or - // regional) will be assigned. - IPAddress string `json:"IPAddress,omitempty"` - - // IPProtocol: The IP protocol to which this rule applies, valid options - // are 'TCP', 'UDP', 'ESP', 'AH' or 'SCTP'. - IPProtocol string `json:"IPProtocol,omitempty"` - - // CreationTimestamp: Creation timestamp in RFC3339 text format (output - // only). - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // Description: An optional textual description of the resource; - // provided by the client when the resource is created. - Description string `json:"description,omitempty"` - - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id uint64 `json:"id,omitempty,string"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // Name: Name of the resource; provided by the client when the resource - // is created. The name must be 1-63 characters long, and comply with - // RFC1035. - Name string `json:"name,omitempty"` - - // PortRange: Applicable only when 'IPProtocol' is 'TCP', 'UDP' or - // 'SCTP', only packets addressed to ports in the specified range will - // be forwarded to 'target'. If 'portRange' is left empty (default - // value), all ports are forwarded. Forwarding rules with the same - // [IPAddress, IPProtocol] pair must have disjoint port ranges. - PortRange string `json:"portRange,omitempty"` - - // Region: URL of the region where the regional forwarding rule resides - // (output only). This field is not applicable to global forwarding - // rules. - Region string `json:"region,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` - - // Target: The URL of the target resource to receive the matched - // traffic. For regional forwarding rules, this target must live in the - // same region as the forwarding rule. For global forwarding rules, this - // target must be a global TargetHttpProxy resource. - Target string `json:"target,omitempty"` -} - -type ForwardingRuleAggregatedList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: A map of scoped forwarding rule lists. - Items map[string]ForwardingRulesScopedList `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type ForwardingRuleList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: The ForwardingRule resources. - Items []*ForwardingRule `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type ForwardingRulesScopedList struct { - // ForwardingRules: List of forwarding rules contained in this scope. - ForwardingRules []*ForwardingRule `json:"forwardingRules,omitempty"` - - // Warning: Informational warning which replaces the list of forwarding - // rules when the list is empty. - Warning *ForwardingRulesScopedListWarning `json:"warning,omitempty"` -} - -type ForwardingRulesScopedListWarning struct { - // Code: The warning type identifier for this warning. - Code string `json:"code,omitempty"` - - // Data: Metadata for this warning in 'key: value' format. - Data []*ForwardingRulesScopedListWarningData `json:"data,omitempty"` - - // Message: Optional human-readable details for this warning. - Message string `json:"message,omitempty"` -} - -type ForwardingRulesScopedListWarningData struct { - // Key: A key for the warning data. - Key string `json:"key,omitempty"` - - // Value: A warning data value corresponding to the key. - Value string `json:"value,omitempty"` -} - -type HealthCheckReference struct { - HealthCheck string `json:"healthCheck,omitempty"` -} - -type HealthStatus struct { - // HealthState: Health state of the instance. - HealthState string `json:"healthState,omitempty"` - - // Instance: URL of the instance resource. - Instance string `json:"instance,omitempty"` - - // IpAddress: The IP address represented by this resource. - IpAddress string `json:"ipAddress,omitempty"` - - // Port: The port on the instance. - Port int64 `json:"port,omitempty"` -} - -type HostRule struct { - Description string `json:"description,omitempty"` - - // Hosts: The list of host patterns to match. They must be valid - // hostnames except that they may start with *. or *-. The * acts like a - // glob and will match any string of atoms (separated by .s and -s) to - // the left. - Hosts []string `json:"hosts,omitempty"` - - // PathMatcher: The name of the PathMatcher to match the path portion of - // the URL, if the this HostRule matches the URL's host portion. - PathMatcher string `json:"pathMatcher,omitempty"` -} - -type HttpHealthCheck struct { - // CheckIntervalSec: How often (in seconds) to send a health check. The - // default value is 5 seconds. - CheckIntervalSec int64 `json:"checkIntervalSec,omitempty"` - - // CreationTimestamp: Creation timestamp in RFC3339 text format (output - // only). - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // Description: An optional textual description of the resource; - // provided by the client when the resource is created. - Description string `json:"description,omitempty"` - - // HealthyThreshold: A so-far unhealthy VM will be marked healthy after - // this many consecutive successes. The default value is 2. - HealthyThreshold int64 `json:"healthyThreshold,omitempty"` - - // Host: The value of the host header in the HTTP health check request. - // If left empty (default value), the public IP on behalf of which this - // health check is performed will be used. - Host string `json:"host,omitempty"` - - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id uint64 `json:"id,omitempty,string"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // Name: Name of the resource; provided by the client when the resource - // is created. The name must be 1-63 characters long, and comply with - // RFC1035. - Name string `json:"name,omitempty"` - - // Port: The TCP port number for the HTTP health check request. The - // default value is 80. - Port int64 `json:"port,omitempty"` - - // RequestPath: The request path of the HTTP health check request. The - // default value is "/". - RequestPath string `json:"requestPath,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` - - // TimeoutSec: How long (in seconds) to wait before claiming failure. - // The default value is 5 seconds. - TimeoutSec int64 `json:"timeoutSec,omitempty"` - - // UnhealthyThreshold: A so-far healthy VM will be marked unhealthy - // after this many consecutive failures. The default value is 2. - UnhealthyThreshold int64 `json:"unhealthyThreshold,omitempty"` -} - -type HttpHealthCheckList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: The HttpHealthCheck resources. - Items []*HttpHealthCheck `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type Image struct { - // ArchiveSizeBytes: Size of the image tar.gz archive stored in Google - // Cloud Storage (in bytes). - ArchiveSizeBytes int64 `json:"archiveSizeBytes,omitempty,string"` - - // CreationTimestamp: Creation timestamp in RFC3339 text format (output - // only). - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // Deprecated: The deprecation status associated with this image. - Deprecated *DeprecationStatus `json:"deprecated,omitempty"` - - // Description: Textual description of the resource; provided by the - // client when the resource is created. - Description string `json:"description,omitempty"` - - // DiskSizeGb: Size of the image when restored onto a disk (in GiB). - DiskSizeGb int64 `json:"diskSizeGb,omitempty,string"` - - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id uint64 `json:"id,omitempty,string"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // Licenses: Public visible licenses. - Licenses []string `json:"licenses,omitempty"` - - // Name: Name of the resource; provided by the client when the resource - // is created. The name must be 1-63 characters long, and comply with - // RFC1035. - Name string `json:"name,omitempty"` - - // RawDisk: The raw disk image parameters. - RawDisk *ImageRawDisk `json:"rawDisk,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` - - // SourceDisk: The source disk used to create this image. - SourceDisk string `json:"sourceDisk,omitempty"` - - // SourceDiskId: The 'id' value of the disk used to create this image. - // This value may be used to determine whether the image was taken from - // the current or a previous instance of a given disk name. - SourceDiskId string `json:"sourceDiskId,omitempty"` - - // SourceType: Must be "RAW"; provided by the client when the disk image - // is created. - SourceType string `json:"sourceType,omitempty"` - - // Status: Status of the image (output only). It will be one of the - // following READY - after image has been successfully created and is - // ready for use FAILED - if creating the image fails for some reason - // PENDING - the image creation is in progress An image can be used to - // create other resources suck as instances only after the image has - // been successfully created and the status is set to READY. - Status string `json:"status,omitempty"` -} - -type ImageRawDisk struct { - // ContainerType: The format used to encode and transmit the block - // device. Should be TAR. This is just a container and transmission - // format and not a runtime format. Provided by the client when the disk - // image is created. - ContainerType string `json:"containerType,omitempty"` - - // Sha1Checksum: An optional SHA1 checksum of the disk image before - // unpackaging; provided by the client when the disk image is created. - Sha1Checksum string `json:"sha1Checksum,omitempty"` - - // Source: The full Google Cloud Storage URL where the disk image is - // stored; provided by the client when the disk image is created. - Source string `json:"source,omitempty"` -} - -type ImageList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: The disk image resources. - Items []*Image `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type Instance struct { - // CanIpForward: Allows this instance to send packets with source IP - // addresses other than its own and receive packets with destination IP - // addresses other than its own. If this instance will be used as an IP - // gateway or it will be set as the next-hop in a Route resource, say - // true. If unsure, leave this set to false. - CanIpForward bool `json:"canIpForward,omitempty"` - - // CreationTimestamp: Creation timestamp in RFC3339 text format (output - // only). - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // Description: An optional textual description of the resource; - // provided by the client when the resource is created. - Description string `json:"description,omitempty"` - - // Disks: Array of disks associated with this instance. Persistent disks - // must be created before you can assign them. - Disks []*AttachedDisk `json:"disks,omitempty"` - - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id uint64 `json:"id,omitempty,string"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // MachineType: URL of the machine type resource describing which - // machine type to use to host the instance; provided by the client when - // the instance is created. - MachineType string `json:"machineType,omitempty"` - - // Metadata: Metadata key/value pairs assigned to this instance. - // Consists of custom metadata or predefined keys; see Instance - // documentation for more information. - Metadata *Metadata `json:"metadata,omitempty"` - - // Name: Name of the resource; provided by the client when the resource - // is created. The name must be 1-63 characters long, and comply with - // RFC1035. - Name string `json:"name,omitempty"` - - // NetworkInterfaces: Array of configurations for this interface. This - // specifies how this interface is configured to interact with other - // network services, such as connecting to the internet. Currently, - // ONE_TO_ONE_NAT is the only access config supported. If there are no - // accessConfigs specified, then this instance will have no external - // internet access. - NetworkInterfaces []*NetworkInterface `json:"networkInterfaces,omitempty"` - - // Scheduling: Scheduling options for this instance. - Scheduling *Scheduling `json:"scheduling,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` - - // ServiceAccounts: A list of service accounts each with specified - // scopes, for which access tokens are to be made available to the - // instance through metadata queries. - ServiceAccounts []*ServiceAccount `json:"serviceAccounts,omitempty"` - - // Status: Instance status. One of the following values: "PROVISIONING", - // "STAGING", "RUNNING", "STOPPING", "STOPPED", "TERMINATED" (output - // only). - Status string `json:"status,omitempty"` - - // StatusMessage: An optional, human-readable explanation of the status - // (output only). - StatusMessage string `json:"statusMessage,omitempty"` - - // Tags: A list of tags to be applied to this instance. Used to identify - // valid sources or targets for network firewalls. Provided by the - // client on instance creation. The tags can be later modified by the - // setTags method. Each tag within the list must comply with RFC1035. - Tags *Tags `json:"tags,omitempty"` - - // Zone: URL of the zone where the instance resides (output only). - Zone string `json:"zone,omitempty"` -} - -type InstanceAggregatedList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: A map of scoped instance lists. - Items map[string]InstancesScopedList `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type InstanceList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: A list of instance resources. - Items []*Instance `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type InstanceProperties struct { - // CanIpForward: Allows instances created based on this template to send - // packets with source IP addresses other than their own and receive - // packets with destination IP addresses other than their own. If these - // instances will be used as an IP gateway or it will be set as the - // next-hop in a Route resource, say true. If unsure, leave this set to - // false. - CanIpForward bool `json:"canIpForward,omitempty"` - - // Description: An optional textual description for the instances - // created based on the instance template resource; provided by the - // client when the template is created. - Description string `json:"description,omitempty"` - - // Disks: Array of disks associated with instance created based on this - // template. - Disks []*AttachedDisk `json:"disks,omitempty"` - - // MachineType: Name of the machine type resource describing which - // machine type to use to host the instances created based on this - // template; provided by the client when the instance template is - // created. - MachineType string `json:"machineType,omitempty"` - - // Metadata: Metadata key/value pairs assigned to instances created - // based on this template. Consists of custom metadata or predefined - // keys; see Instance documentation for more information. - Metadata *Metadata `json:"metadata,omitempty"` - - // NetworkInterfaces: Array of configurations for this interface. This - // specifies how this interface is configured to interact with other - // network services, such as connecting to the internet. Currently, - // ONE_TO_ONE_NAT is the only access config supported. If there are no - // accessConfigs specified, then this instances created based based on - // this template will have no external internet access. - NetworkInterfaces []*NetworkInterface `json:"networkInterfaces,omitempty"` - - // Scheduling: Scheduling options for the instances created based on - // this template. - Scheduling *Scheduling `json:"scheduling,omitempty"` - - // ServiceAccounts: A list of service accounts each with specified - // scopes, for which access tokens are to be made available to the - // instances created based on this template, through metadata queries. - ServiceAccounts []*ServiceAccount `json:"serviceAccounts,omitempty"` - - // Tags: A list of tags to be applied to the instances created based on - // this template used to identify valid sources or targets for network - // firewalls. Provided by the client on instance creation. The tags can - // be later modified by the setTags method. Each tag within the list - // must comply with RFC1035. - Tags *Tags `json:"tags,omitempty"` -} - -type InstanceReference struct { - Instance string `json:"instance,omitempty"` -} - -type InstanceTemplate struct { - // CreationTimestamp: Creation timestamp in RFC3339 text format (output - // only). - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // Description: An optional textual description of the instance template - // resource; provided by the client when the resource is created. - Description string `json:"description,omitempty"` - - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id uint64 `json:"id,omitempty,string"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // Name: Name of the instance template resource; provided by the client - // when the resource is created. The name must be 1-63 characters long, - // and comply with RFC1035 - Name string `json:"name,omitempty"` - - // Properties: The instance properties portion of this instance template - // resource. - Properties *InstanceProperties `json:"properties,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type InstanceTemplateList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: A list of instance template resources. - Items []*InstanceTemplate `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type InstancesScopedList struct { - // Instances: List of instances contained in this scope. - Instances []*Instance `json:"instances,omitempty"` - - // Warning: Informational warning which replaces the list of instances - // when the list is empty. - Warning *InstancesScopedListWarning `json:"warning,omitempty"` -} - -type InstancesScopedListWarning struct { - // Code: The warning type identifier for this warning. - Code string `json:"code,omitempty"` - - // Data: Metadata for this warning in 'key: value' format. - Data []*InstancesScopedListWarningData `json:"data,omitempty"` - - // Message: Optional human-readable details for this warning. - Message string `json:"message,omitempty"` -} - -type InstancesScopedListWarningData struct { - // Key: A key for the warning data. - Key string `json:"key,omitempty"` - - // Value: A warning data value corresponding to the key. - Value string `json:"value,omitempty"` -} - -type License struct { - // ChargesUseFee: If true, the customer will be charged license fee for - // running software that contains this license on an instance. - ChargesUseFee bool `json:"chargesUseFee,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // Name: Name of the resource; provided by the client when the resource - // is created. The name must be 1-63 characters long, and comply with - // RFC1035. - Name string `json:"name,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type MachineType struct { - // CreationTimestamp: Creation timestamp in RFC3339 text format (output - // only). - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // Deprecated: The deprecation status associated with this machine type. - Deprecated *DeprecationStatus `json:"deprecated,omitempty"` - - // Description: An optional textual description of the resource. - Description string `json:"description,omitempty"` - - // GuestCpus: Count of CPUs exposed to the instance. - GuestCpus int64 `json:"guestCpus,omitempty"` - - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id uint64 `json:"id,omitempty,string"` - - // ImageSpaceGb: Space allotted for the image, defined in GB. - ImageSpaceGb int64 `json:"imageSpaceGb,omitempty"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // MaximumPersistentDisks: Maximum persistent disks allowed. - MaximumPersistentDisks int64 `json:"maximumPersistentDisks,omitempty"` - - // MaximumPersistentDisksSizeGb: Maximum total persistent disks size - // (GB) allowed. - MaximumPersistentDisksSizeGb int64 `json:"maximumPersistentDisksSizeGb,omitempty,string"` - - // MemoryMb: Physical memory assigned to the instance, defined in MB. - MemoryMb int64 `json:"memoryMb,omitempty"` - - // Name: Name of the resource. - Name string `json:"name,omitempty"` - - // ScratchDisks: List of extended scratch disks assigned to the - // instance. - ScratchDisks []*MachineTypeScratchDisks `json:"scratchDisks,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` - - // Zone: Url of the zone where the machine type resides (output only). - Zone string `json:"zone,omitempty"` -} - -type MachineTypeScratchDisks struct { - // DiskGb: Size of the scratch disk, defined in GB. - DiskGb int64 `json:"diskGb,omitempty"` -} - -type MachineTypeAggregatedList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: A map of scoped machine type lists. - Items map[string]MachineTypesScopedList `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type MachineTypeList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: The machine type resources. - Items []*MachineType `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type MachineTypesScopedList struct { - // MachineTypes: List of machine types contained in this scope. - MachineTypes []*MachineType `json:"machineTypes,omitempty"` - - // Warning: Informational warning which replaces the list of machine - // types when the list is empty. - Warning *MachineTypesScopedListWarning `json:"warning,omitempty"` -} - -type MachineTypesScopedListWarning struct { - // Code: The warning type identifier for this warning. - Code string `json:"code,omitempty"` - - // Data: Metadata for this warning in 'key: value' format. - Data []*MachineTypesScopedListWarningData `json:"data,omitempty"` - - // Message: Optional human-readable details for this warning. - Message string `json:"message,omitempty"` -} - -type MachineTypesScopedListWarningData struct { - // Key: A key for the warning data. - Key string `json:"key,omitempty"` - - // Value: A warning data value corresponding to the key. - Value string `json:"value,omitempty"` -} - -type Metadata struct { - // Fingerprint: Fingerprint of this resource. A hash of the metadata's - // contents. This field is used for optimistic locking. An up-to-date - // metadata fingerprint must be provided in order to modify metadata. - Fingerprint string `json:"fingerprint,omitempty"` - - // Items: Array of key/value pairs. The total size of all keys and - // values must be less than 512 KB. - Items []*MetadataItems `json:"items,omitempty"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` -} - -type MetadataItems struct { - // Key: Key for the metadata entry. Keys must conform to the following - // regexp: [a-zA-Z0-9-_]+, and be less than 128 bytes in length. This is - // reflected as part of a URL in the metadata server. Additionally, to - // avoid ambiguity, keys must not conflict with any other metadata keys - // for the project. - Key string `json:"key,omitempty"` - - // Value: Value for the metadata entry. These are free-form strings, and - // only have meaning as interpreted by the image running in the - // instance. The only restriction placed on values is that their size - // must be less than or equal to 32768 bytes. - Value string `json:"value,omitempty"` -} - -type Network struct { - // IPv4Range: Required; The range of internal addresses that are legal - // on this network. This range is a CIDR specification, for example: - // 192.168.0.0/16. Provided by the client when the network is created. - IPv4Range string `json:"IPv4Range,omitempty"` - - // CreationTimestamp: Creation timestamp in RFC3339 text format (output - // only). - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // Description: An optional textual description of the resource; - // provided by the client when the resource is created. - Description string `json:"description,omitempty"` - - // GatewayIPv4: An optional address that is used for default routing to - // other networks. This must be within the range specified by IPv4Range, - // and is typically the first usable address in that range. If not - // specified, the default value is the first usable address in - // IPv4Range. - GatewayIPv4 string `json:"gatewayIPv4,omitempty"` - - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id uint64 `json:"id,omitempty,string"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // Name: Name of the resource; provided by the client when the resource - // is created. The name must be 1-63 characters long, and comply with - // RFC1035. - Name string `json:"name,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type NetworkInterface struct { - // AccessConfigs: Array of configurations for this interface. This - // specifies how this interface is configured to interact with other - // network services, such as connecting to the internet. Currently, - // ONE_TO_ONE_NAT is the only access config supported. If there are no - // accessConfigs specified, then this instance will have no external - // internet access. - AccessConfigs []*AccessConfig `json:"accessConfigs,omitempty"` - - // Name: Name of the network interface, determined by the server; for - // network devices, these are e.g. eth0, eth1, etc. (output only). - Name string `json:"name,omitempty"` - - // Network: URL of the network resource attached to this interface. - Network string `json:"network,omitempty"` - - // NetworkIP: An optional IPV4 internal network address assigned to the - // instance for this network interface (output only). - NetworkIP string `json:"networkIP,omitempty"` -} - -type NetworkList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: The network resources. - Items []*Network `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type Operation struct { - // ClientOperationId: An optional identifier specified by the client - // when the mutation was initiated. Must be unique for all operation - // resources in the project (output only). - ClientOperationId string `json:"clientOperationId,omitempty"` - - // CreationTimestamp: Creation timestamp in RFC3339 text format (output - // only). - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // EndTime: The time that this operation was completed. This is in RFC - // 3339 format (output only). - EndTime string `json:"endTime,omitempty"` - - // Error: If errors occurred during processing of this operation, this - // field will be populated (output only). - Error *OperationError `json:"error,omitempty"` - - // HttpErrorMessage: If operation fails, the HTTP error message - // returned, e.g. NOT FOUND. (output only). - HttpErrorMessage string `json:"httpErrorMessage,omitempty"` - - // HttpErrorStatusCode: If operation fails, the HTTP error status code - // returned, e.g. 404. (output only). - HttpErrorStatusCode int64 `json:"httpErrorStatusCode,omitempty"` - - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id uint64 `json:"id,omitempty,string"` - - // InsertTime: The time that this operation was requested. This is in - // RFC 3339 format (output only). - InsertTime string `json:"insertTime,omitempty"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // Name: Name of the resource (output only). - Name string `json:"name,omitempty"` - - // OperationType: Type of the operation. Examples include "insert", - // "update", and "delete" (output only). - OperationType string `json:"operationType,omitempty"` - - // Progress: An optional progress indicator that ranges from 0 to 100. - // There is no requirement that this be linear or support any - // granularity of operations. This should not be used to guess at when - // the operation will be complete. This number should be monotonically - // increasing as the operation progresses (output only). - Progress int64 `json:"progress,omitempty"` - - // Region: URL of the region where the operation resides (output only). - Region string `json:"region,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` - - // StartTime: The time that this operation was started by the server. - // This is in RFC 3339 format (output only). - StartTime string `json:"startTime,omitempty"` - - // Status: Status of the operation. Can be one of the following: - // "PENDING", "RUNNING", or "DONE" (output only). - Status string `json:"status,omitempty"` - - // StatusMessage: An optional textual description of the current status - // of the operation (output only). - StatusMessage string `json:"statusMessage,omitempty"` - - // TargetId: Unique target id which identifies a particular incarnation - // of the target (output only). - TargetId uint64 `json:"targetId,omitempty,string"` - - // TargetLink: URL of the resource the operation is mutating (output - // only). - TargetLink string `json:"targetLink,omitempty"` - - // User: User who requested the operation, for example - // "user@example.com" (output only). - User string `json:"user,omitempty"` - - // Warnings: If warning messages generated during processing of this - // operation, this field will be populated (output only). - Warnings []*OperationWarnings `json:"warnings,omitempty"` - - // Zone: URL of the zone where the operation resides (output only). - Zone string `json:"zone,omitempty"` -} - -type OperationError struct { - // Errors: The array of errors encountered while processing this - // operation. - Errors []*OperationErrorErrors `json:"errors,omitempty"` -} - -type OperationErrorErrors struct { - // Code: The error type identifier for this error. - Code string `json:"code,omitempty"` - - // Location: Indicates the field in the request which caused the error. - // This property is optional. - Location string `json:"location,omitempty"` - - // Message: An optional, human-readable error message. - Message string `json:"message,omitempty"` -} - -type OperationWarnings struct { - // Code: The warning type identifier for this warning. - Code string `json:"code,omitempty"` - - // Data: Metadata for this warning in 'key: value' format. - Data []*OperationWarningsData `json:"data,omitempty"` - - // Message: Optional human-readable details for this warning. - Message string `json:"message,omitempty"` -} - -type OperationWarningsData struct { - // Key: A key for the warning data. - Key string `json:"key,omitempty"` - - // Value: A warning data value corresponding to the key. - Value string `json:"value,omitempty"` -} - -type OperationAggregatedList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: A map of scoped operation lists. - Items map[string]OperationsScopedList `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type OperationList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: The operation resources. - Items []*Operation `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type OperationsScopedList struct { - // Operations: List of operations contained in this scope. - Operations []*Operation `json:"operations,omitempty"` - - // Warning: Informational warning which replaces the list of operations - // when the list is empty. - Warning *OperationsScopedListWarning `json:"warning,omitempty"` -} - -type OperationsScopedListWarning struct { - // Code: The warning type identifier for this warning. - Code string `json:"code,omitempty"` - - // Data: Metadata for this warning in 'key: value' format. - Data []*OperationsScopedListWarningData `json:"data,omitempty"` - - // Message: Optional human-readable details for this warning. - Message string `json:"message,omitempty"` -} - -type OperationsScopedListWarningData struct { - // Key: A key for the warning data. - Key string `json:"key,omitempty"` - - // Value: A warning data value corresponding to the key. - Value string `json:"value,omitempty"` -} - -type PathMatcher struct { - // DefaultService: The URL to the BackendService resource. This will be - // used if none of the 'pathRules' defined by this PathMatcher is met by - // the URL's path portion. - DefaultService string `json:"defaultService,omitempty"` - - Description string `json:"description,omitempty"` - - // Name: The name to which this PathMatcher is referred by the HostRule. - Name string `json:"name,omitempty"` - - // PathRules: The list of path rules. - PathRules []*PathRule `json:"pathRules,omitempty"` -} - -type PathRule struct { - // Paths: The list of path patterns to match. Each must start with / and - // the only place a * is allowed is at the end following a /. The string - // fed to the path matcher does not include any text after the first ? - // or #, and those chars are not allowed here. - Paths []string `json:"paths,omitempty"` - - // Service: The URL of the BackendService resource if this rule is - // matched. - Service string `json:"service,omitempty"` -} - -type Project struct { - // CommonInstanceMetadata: Metadata key/value pairs available to all - // instances contained in this project. - CommonInstanceMetadata *Metadata `json:"commonInstanceMetadata,omitempty"` - - // CreationTimestamp: Creation timestamp in RFC3339 text format (output - // only). - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // Description: An optional textual description of the resource. - Description string `json:"description,omitempty"` - - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id uint64 `json:"id,omitempty,string"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // Name: Name of the resource. - Name string `json:"name,omitempty"` - - // Quotas: Quotas assigned to this project. - Quotas []*Quota `json:"quotas,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` - - // UsageExportLocation: The location in Cloud Storage and naming method - // of the daily usage report. - UsageExportLocation *UsageExportLocation `json:"usageExportLocation,omitempty"` -} - -type Quota struct { - // Limit: Quota limit for this metric. - Limit float64 `json:"limit,omitempty"` - - // Metric: Name of the quota metric. - Metric string `json:"metric,omitempty"` - - // Usage: Current usage of this metric. - Usage float64 `json:"usage,omitempty"` -} - -type Region struct { - // CreationTimestamp: Creation timestamp in RFC3339 text format (output - // only). - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // Deprecated: The deprecation status associated with this region. - Deprecated *DeprecationStatus `json:"deprecated,omitempty"` - - // Description: Textual description of the resource. - Description string `json:"description,omitempty"` - - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id uint64 `json:"id,omitempty,string"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // Name: Name of the resource. - Name string `json:"name,omitempty"` - - // Quotas: Quotas assigned to this region. - Quotas []*Quota `json:"quotas,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` - - // Status: Status of the region, "UP" or "DOWN". - Status string `json:"status,omitempty"` - - // Zones: A list of zones homed in this region, in the form of resource - // URLs. - Zones []string `json:"zones,omitempty"` -} - -type RegionList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: The region resources. - Items []*Region `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type ResourceGroupReference struct { - // Group: A URI referencing one of the resource views listed in the - // backend service. - Group string `json:"group,omitempty"` -} - -type Route struct { - // CreationTimestamp: Creation timestamp in RFC3339 text format (output - // only). - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // Description: An optional textual description of the resource; - // provided by the client when the resource is created. - Description string `json:"description,omitempty"` - - // DestRange: Which packets does this route apply to? - DestRange string `json:"destRange,omitempty"` - - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id uint64 `json:"id,omitempty,string"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // Name: Name of the resource; provided by the client when the resource - // is created. The name must be 1-63 characters long, and comply with - // RFC1035. - Name string `json:"name,omitempty"` - - // Network: URL of the network to which this route is applied; provided - // by the client when the route is created. - Network string `json:"network,omitempty"` - - // NextHopGateway: The URL to a gateway that should handle matching - // packets. - NextHopGateway string `json:"nextHopGateway,omitempty"` - - // NextHopInstance: The URL to an instance that should handle matching - // packets. - NextHopInstance string `json:"nextHopInstance,omitempty"` - - // NextHopIp: The network IP address of an instance that should handle - // matching packets. - NextHopIp string `json:"nextHopIp,omitempty"` - - // NextHopNetwork: The URL of the local network if it should handle - // matching packets. - NextHopNetwork string `json:"nextHopNetwork,omitempty"` - - // Priority: Breaks ties between Routes of equal specificity. Routes - // with smaller values win when tied with routes with larger values. - Priority int64 `json:"priority,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` - - // Tags: A list of instance tags to which this route applies. - Tags []string `json:"tags,omitempty"` - - // Warnings: If potential misconfigurations are detected for this route, - // this field will be populated with warning messages. - Warnings []*RouteWarnings `json:"warnings,omitempty"` -} - -type RouteWarnings struct { - // Code: The warning type identifier for this warning. - Code string `json:"code,omitempty"` - - // Data: Metadata for this warning in 'key: value' format. - Data []*RouteWarningsData `json:"data,omitempty"` - - // Message: Optional human-readable details for this warning. - Message string `json:"message,omitempty"` -} - -type RouteWarningsData struct { - // Key: A key for the warning data. - Key string `json:"key,omitempty"` - - // Value: A warning data value corresponding to the key. - Value string `json:"value,omitempty"` -} - -type RouteList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: The route resources. - Items []*Route `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type Scheduling struct { - // AutomaticRestart: Whether the Instance should be automatically - // restarted whenever it is terminated by Compute Engine (not terminated - // by user). - AutomaticRestart bool `json:"automaticRestart,omitempty"` - - // OnHostMaintenance: How the instance should behave when the host - // machine undergoes maintenance that may temporarily impact instance - // performance. - OnHostMaintenance string `json:"onHostMaintenance,omitempty"` -} - -type SerialPortOutput struct { - // Contents: The contents of the console output. - Contents string `json:"contents,omitempty"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type ServiceAccount struct { - // Email: Email address of the service account. - Email string `json:"email,omitempty"` - - // Scopes: The list of scopes to be made available for this service - // account. - Scopes []string `json:"scopes,omitempty"` -} - -type Snapshot struct { - // CreationTimestamp: Creation timestamp in RFC3339 text format (output - // only). - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // Description: An optional textual description of the resource; - // provided by the client when the resource is created. - Description string `json:"description,omitempty"` - - // DiskSizeGb: Size of the persistent disk snapshot, specified in GB - // (output only). - DiskSizeGb int64 `json:"diskSizeGb,omitempty,string"` - - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id uint64 `json:"id,omitempty,string"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // Licenses: Public visible licenses. - Licenses []string `json:"licenses,omitempty"` - - // Name: Name of the resource; provided by the client when the resource - // is created. The name must be 1-63 characters long, and comply with - // RFC1035. - Name string `json:"name,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` - - // SourceDisk: The source disk used to create this snapshot. - SourceDisk string `json:"sourceDisk,omitempty"` - - // SourceDiskId: The 'id' value of the disk used to create this - // snapshot. This value may be used to determine whether the snapshot - // was taken from the current or a previous instance of a given disk - // name. - SourceDiskId string `json:"sourceDiskId,omitempty"` - - // Status: The status of the persistent disk snapshot (output only). - Status string `json:"status,omitempty"` - - // StorageBytes: A size of the the storage used by the snapshot. As - // snapshots share storage this number is expected to change with - // snapshot creation/deletion. - StorageBytes int64 `json:"storageBytes,omitempty,string"` - - // StorageBytesStatus: An indicator whether storageBytes is in a stable - // state, or it is being adjusted as a result of shared storage - // reallocation. - StorageBytesStatus string `json:"storageBytesStatus,omitempty"` -} - -type SnapshotList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: The persistent snapshot resources. - Items []*Snapshot `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type Tags struct { - // Fingerprint: Fingerprint of this resource. A hash of the tags stored - // in this object. This field is used optimistic locking. An up-to-date - // tags fingerprint must be provided in order to modify tags. - Fingerprint string `json:"fingerprint,omitempty"` - - // Items: An array of tags. Each tag must be 1-63 characters long, and - // comply with RFC1035. - Items []string `json:"items,omitempty"` -} - -type TargetHttpProxy struct { - // CreationTimestamp: Creation timestamp in RFC3339 text format (output - // only). - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // Description: An optional textual description of the resource; - // provided by the client when the resource is created. - Description string `json:"description,omitempty"` - - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id uint64 `json:"id,omitempty,string"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // Name: Name of the resource; provided by the client when the resource - // is created. The name must be 1-63 characters long, and comply with - // RFC1035. - Name string `json:"name,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` - - // UrlMap: URL to the UrlMap resource that defines the mapping from URL - // to the BackendService. - UrlMap string `json:"urlMap,omitempty"` -} - -type TargetHttpProxyList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: The TargetHttpProxy resources. - Items []*TargetHttpProxy `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type TargetInstance struct { - // CreationTimestamp: Creation timestamp in RFC3339 text format (output - // only). - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // Description: An optional textual description of the resource; - // provided by the client when the resource is created. - Description string `json:"description,omitempty"` - - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id uint64 `json:"id,omitempty,string"` - - // Instance: The URL to the instance that terminates the relevant - // traffic. - Instance string `json:"instance,omitempty"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // Name: Name of the resource; provided by the client when the resource - // is created. The name must be 1-63 characters long, and comply with - // RFC1035. - Name string `json:"name,omitempty"` - - // NatPolicy: NAT option controlling how IPs are NAT'ed to the VM. - // Currently only NO_NAT (default value) is supported. - NatPolicy string `json:"natPolicy,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` - - // Zone: URL of the zone where the target instance resides (output - // only). - Zone string `json:"zone,omitempty"` -} - -type TargetInstanceAggregatedList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: A map of scoped target instance lists. - Items map[string]TargetInstancesScopedList `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type TargetInstanceList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: The TargetInstance resources. - Items []*TargetInstance `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type TargetInstancesScopedList struct { - // TargetInstances: List of target instances contained in this scope. - TargetInstances []*TargetInstance `json:"targetInstances,omitempty"` - - // Warning: Informational warning which replaces the list of addresses - // when the list is empty. - Warning *TargetInstancesScopedListWarning `json:"warning,omitempty"` -} - -type TargetInstancesScopedListWarning struct { - // Code: The warning type identifier for this warning. - Code string `json:"code,omitempty"` - - // Data: Metadata for this warning in 'key: value' format. - Data []*TargetInstancesScopedListWarningData `json:"data,omitempty"` - - // Message: Optional human-readable details for this warning. - Message string `json:"message,omitempty"` -} - -type TargetInstancesScopedListWarningData struct { - // Key: A key for the warning data. - Key string `json:"key,omitempty"` - - // Value: A warning data value corresponding to the key. - Value string `json:"value,omitempty"` -} - -type TargetPool struct { - // BackupPool: This field is applicable only when the containing target - // pool is serving a forwarding rule as the primary pool, and its - // 'failoverRatio' field is properly set to a value between [0, - // 1]. - // - // 'backupPool' and 'failoverRatio' together define the fallback - // behavior of the primary target pool: if the ratio of the healthy VMs - // in the primary pool is at or below 'failoverRatio', traffic arriving - // at the load-balanced IP will be directed to the backup pool. - // - // In case - // where 'failoverRatio' and 'backupPool' are not set, or all the VMs in - // the backup pool are unhealthy, the traffic will be directed back to - // the primary pool in the "force" mode, where traffic will be spread to - // the healthy VMs with the best effort, or to all VMs when no VM is - // healthy. - BackupPool string `json:"backupPool,omitempty"` - - // CreationTimestamp: Creation timestamp in RFC3339 text format (output - // only). - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // Description: An optional textual description of the resource; - // provided by the client when the resource is created. - Description string `json:"description,omitempty"` - - // FailoverRatio: This field is applicable only when the containing - // target pool is serving a forwarding rule as the primary pool (i.e., - // not as a backup pool to some other target pool). The value of the - // field must be in [0, 1]. - // - // If set, 'backupPool' must also be set. They - // together define the fallback behavior of the primary target pool: if - // the ratio of the healthy VMs in the primary pool is at or below this - // number, traffic arriving at the load-balanced IP will be directed to - // the backup pool. - // - // In case where 'failoverRatio' is not set or all the - // VMs in the backup pool are unhealthy, the traffic will be directed - // back to the primary pool in the "force" mode, where traffic will be - // spread to the healthy VMs with the best effort, or to all VMs when no - // VM is healthy. - FailoverRatio float64 `json:"failoverRatio,omitempty"` - - // HealthChecks: A list of URLs to the HttpHealthCheck resource. A - // member VM in this pool is considered healthy if and only if all - // specified health checks pass. An empty list means all member VMs will - // be considered healthy at all times. - HealthChecks []string `json:"healthChecks,omitempty"` - - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id uint64 `json:"id,omitempty,string"` - - // Instances: A list of resource URLs to the member VMs serving this - // pool. They must live in zones contained in the same region as this - // pool. - Instances []string `json:"instances,omitempty"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // Name: Name of the resource; provided by the client when the resource - // is created. The name must be 1-63 characters long, and comply with - // RFC1035. - Name string `json:"name,omitempty"` - - // Region: URL of the region where the target pool resides (output - // only). - Region string `json:"region,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` - - // SessionAffinity: Sesssion affinity option, must be one of the - // following values: 'NONE': Connections from the same client IP may go - // to any VM in the pool; 'CLIENT_IP': Connections from the same client - // IP will go to the same VM in the pool while that VM remains healthy. - // 'CLIENT_IP_PROTO': Connections from the same client IP with the same - // IP protocol will go to the same VM in the pool while that VM remains - // healthy. - SessionAffinity string `json:"sessionAffinity,omitempty"` -} - -type TargetPoolAggregatedList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: A map of scoped target pool lists. - Items map[string]TargetPoolsScopedList `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type TargetPoolInstanceHealth struct { - HealthStatus []*HealthStatus `json:"healthStatus,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` -} - -type TargetPoolList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: The TargetPool resources. - Items []*TargetPool `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type TargetPoolsAddHealthCheckRequest struct { - // HealthChecks: Health check URLs to be added to targetPool. - HealthChecks []*HealthCheckReference `json:"healthChecks,omitempty"` -} - -type TargetPoolsAddInstanceRequest struct { - // Instances: URLs of the instances to be added to targetPool. - Instances []*InstanceReference `json:"instances,omitempty"` -} - -type TargetPoolsRemoveHealthCheckRequest struct { - // HealthChecks: Health check URLs to be removed from targetPool. - HealthChecks []*HealthCheckReference `json:"healthChecks,omitempty"` -} - -type TargetPoolsRemoveInstanceRequest struct { - // Instances: URLs of the instances to be removed from targetPool. - Instances []*InstanceReference `json:"instances,omitempty"` -} - -type TargetPoolsScopedList struct { - // TargetPools: List of target pools contained in this scope. - TargetPools []*TargetPool `json:"targetPools,omitempty"` - - // Warning: Informational warning which replaces the list of addresses - // when the list is empty. - Warning *TargetPoolsScopedListWarning `json:"warning,omitempty"` -} - -type TargetPoolsScopedListWarning struct { - // Code: The warning type identifier for this warning. - Code string `json:"code,omitempty"` - - // Data: Metadata for this warning in 'key: value' format. - Data []*TargetPoolsScopedListWarningData `json:"data,omitempty"` - - // Message: Optional human-readable details for this warning. - Message string `json:"message,omitempty"` -} - -type TargetPoolsScopedListWarningData struct { - // Key: A key for the warning data. - Key string `json:"key,omitempty"` - - // Value: A warning data value corresponding to the key. - Value string `json:"value,omitempty"` -} - -type TargetReference struct { - Target string `json:"target,omitempty"` -} - -type TestFailure struct { - ActualService string `json:"actualService,omitempty"` - - ExpectedService string `json:"expectedService,omitempty"` - - Host string `json:"host,omitempty"` - - Path string `json:"path,omitempty"` -} - -type UrlMap struct { - // CreationTimestamp: Creation timestamp in RFC3339 text format (output - // only). - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // DefaultService: The URL of the BackendService resource if none of the - // hostRules match. - DefaultService string `json:"defaultService,omitempty"` - - // Description: An optional textual description of the resource; - // provided by the client when the resource is created. - Description string `json:"description,omitempty"` - - // Fingerprint: Fingerprint of this resource. A hash of the contents - // stored in this object. This field is used in optimistic locking. This - // field will be ignored when inserting a UrlMap. An up-to-date - // fingerprint must be provided in order to update the UrlMap. - Fingerprint string `json:"fingerprint,omitempty"` - - // HostRules: The list of HostRules to use against the URL. - HostRules []*HostRule `json:"hostRules,omitempty"` - - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id uint64 `json:"id,omitempty,string"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // Name: Name of the resource; provided by the client when the resource - // is created. The name must be 1-63 characters long, and comply with - // RFC1035. - Name string `json:"name,omitempty"` - - // PathMatchers: The list of named PathMatchers to use against the URL. - PathMatchers []*PathMatcher `json:"pathMatchers,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` - - // Tests: The list of expected URL mappings. Request to update this - // UrlMap will succeed only all of the test cases pass. - Tests []*UrlMapTest `json:"tests,omitempty"` -} - -type UrlMapList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: The UrlMap resources. - Items []*UrlMap `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -type UrlMapReference struct { - UrlMap string `json:"urlMap,omitempty"` -} - -type UrlMapTest struct { - // Description: Description of this test case. - Description string `json:"description,omitempty"` - - // Host: Host portion of the URL. - Host string `json:"host,omitempty"` - - // Path: Path portion of the URL. - Path string `json:"path,omitempty"` - - // Service: Expected BackendService resource the given URL should be - // mapped to. - Service string `json:"service,omitempty"` -} - -type UrlMapValidationResult struct { - LoadErrors []string `json:"loadErrors,omitempty"` - - // LoadSucceeded: Whether the given UrlMap can be successfully loaded. - // If false, 'loadErrors' indicates the reasons. - LoadSucceeded bool `json:"loadSucceeded,omitempty"` - - TestFailures []*TestFailure `json:"testFailures,omitempty"` - - // TestPassed: If successfully loaded, this field indicates whether the - // test passed. If false, 'testFailures's indicate the reason of - // failure. - TestPassed bool `json:"testPassed,omitempty"` -} - -type UrlMapsValidateRequest struct { - // Resource: Content of the UrlMap to be validated. - Resource *UrlMap `json:"resource,omitempty"` -} - -type UrlMapsValidateResponse struct { - Result *UrlMapValidationResult `json:"result,omitempty"` -} - -type UsageExportLocation struct { - // BucketName: The name of an existing bucket in Cloud Storage where the - // usage report object is stored. The Google Service Account is granted - // write access to this bucket. This is simply the bucket name, with no - // "gs://" or "https://storage.googleapis.com/" in front of it. - BucketName string `json:"bucketName,omitempty"` - - // ReportNamePrefix: An optional prefix for the name of the usage report - // object stored in bucket_name. If not supplied, defaults to "usage_". - // The report is stored as a CSV file named _gce_.csv. where is the day - // of the usage according to Pacific Time. The prefix should conform to - // Cloud Storage object naming conventions. - ReportNamePrefix string `json:"reportNamePrefix,omitempty"` -} - -type Zone struct { - // CreationTimestamp: Creation timestamp in RFC3339 text format (output - // only). - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // Deprecated: The deprecation status associated with this zone. - Deprecated *DeprecationStatus `json:"deprecated,omitempty"` - - // Description: Textual description of the resource. - Description string `json:"description,omitempty"` - - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id uint64 `json:"id,omitempty,string"` - - // Kind: Type of the resource. - Kind string `json:"kind,omitempty"` - - // MaintenanceWindows: Scheduled maintenance windows for the zone. When - // the zone is in a maintenance window, all resources which reside in - // the zone will be unavailable. - MaintenanceWindows []*ZoneMaintenanceWindows `json:"maintenanceWindows,omitempty"` - - // Name: Name of the resource. - Name string `json:"name,omitempty"` - - // Region: Full URL reference to the region which hosts the zone (output - // only). - Region string `json:"region,omitempty"` - - // SelfLink: Server defined URL for the resource (output only). - SelfLink string `json:"selfLink,omitempty"` - - // Status: Status of the zone. "UP" or "DOWN". - Status string `json:"status,omitempty"` -} - -type ZoneMaintenanceWindows struct { - // BeginTime: Begin time of the maintenance window, in RFC 3339 format. - BeginTime string `json:"beginTime,omitempty"` - - // Description: Textual description of the maintenance window. - Description string `json:"description,omitempty"` - - // EndTime: End time of the maintenance window, in RFC 3339 format. - EndTime string `json:"endTime,omitempty"` - - // Name: Name of the maintenance window. - Name string `json:"name,omitempty"` -} - -type ZoneList struct { - // Id: Unique identifier for the resource; defined by the server (output - // only). - Id string `json:"id,omitempty"` - - // Items: The zone resources. - Items []*Zone `json:"items,omitempty"` - - // Kind: Type of resource. - Kind string `json:"kind,omitempty"` - - // NextPageToken: A token used to continue a truncated list request - // (output only). - NextPageToken string `json:"nextPageToken,omitempty"` - - // SelfLink: Server defined URL for this resource (output only). - SelfLink string `json:"selfLink,omitempty"` -} - -// method id "compute.addresses.aggregatedList": - -type AddressesAggregatedListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// AggregatedList: Retrieves the list of addresses grouped by scope. -func (r *AddressesService) AggregatedList(project string) *AddressesAggregatedListCall { - c := &AddressesAggregatedListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *AddressesAggregatedListCall) Filter(filter string) *AddressesAggregatedListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *AddressesAggregatedListCall) MaxResults(maxResults int64) *AddressesAggregatedListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *AddressesAggregatedListCall) PageToken(pageToken string) *AddressesAggregatedListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *AddressesAggregatedListCall) Fields(s ...googleapi.Field) *AddressesAggregatedListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *AddressesAggregatedListCall) Do() (*AddressAggregatedList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/addresses") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *AddressAggregatedList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of addresses grouped by scope.", - // "httpMethod": "GET", - // "id": "compute.addresses.aggregatedList", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/aggregated/addresses", - // "response": { - // "$ref": "AddressAggregatedList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.addresses.delete": - -type AddressesDeleteCall struct { - s *Service - project string - region string - address string - opt_ map[string]interface{} -} - -// Delete: Deletes the specified address resource. -func (r *AddressesService) Delete(project string, region string, address string) *AddressesDeleteCall { - c := &AddressesDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - c.address = address - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *AddressesDeleteCall) Fields(s ...googleapi.Field) *AddressesDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *AddressesDeleteCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/addresses/{address}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("DELETE", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - "address": c.address, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Deletes the specified address resource.", - // "httpMethod": "DELETE", - // "id": "compute.addresses.delete", - // "parameterOrder": [ - // "project", - // "region", - // "address" - // ], - // "parameters": { - // "address": { - // "description": "Name of the address resource to delete.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the region scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}/addresses/{address}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.addresses.get": - -type AddressesGetCall struct { - s *Service - project string - region string - address string - opt_ map[string]interface{} -} - -// Get: Returns the specified address resource. -func (r *AddressesService) Get(project string, region string, address string) *AddressesGetCall { - c := &AddressesGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - c.address = address - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *AddressesGetCall) Fields(s ...googleapi.Field) *AddressesGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *AddressesGetCall) Do() (*Address, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/addresses/{address}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - "address": c.address, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Address - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified address resource.", - // "httpMethod": "GET", - // "id": "compute.addresses.get", - // "parameterOrder": [ - // "project", - // "region", - // "address" - // ], - // "parameters": { - // "address": { - // "description": "Name of the address resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the region scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}/addresses/{address}", - // "response": { - // "$ref": "Address" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.addresses.insert": - -type AddressesInsertCall struct { - s *Service - project string - region string - address *Address - opt_ map[string]interface{} -} - -// Insert: Creates an address resource in the specified project using -// the data included in the request. -func (r *AddressesService) Insert(project string, region string, address *Address) *AddressesInsertCall { - c := &AddressesInsertCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - c.address = address - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *AddressesInsertCall) Fields(s ...googleapi.Field) *AddressesInsertCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *AddressesInsertCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.address) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/addresses") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Creates an address resource in the specified project using the data included in the request.", - // "httpMethod": "POST", - // "id": "compute.addresses.insert", - // "parameterOrder": [ - // "project", - // "region" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the region scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}/addresses", - // "request": { - // "$ref": "Address" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.addresses.list": - -type AddressesListCall struct { - s *Service - project string - region string - opt_ map[string]interface{} -} - -// List: Retrieves the list of address resources contained within the -// specified region. -func (r *AddressesService) List(project string, region string) *AddressesListCall { - c := &AddressesListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *AddressesListCall) Filter(filter string) *AddressesListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *AddressesListCall) MaxResults(maxResults int64) *AddressesListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *AddressesListCall) PageToken(pageToken string) *AddressesListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *AddressesListCall) Fields(s ...googleapi.Field) *AddressesListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *AddressesListCall) Do() (*AddressList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/addresses") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *AddressList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of address resources contained within the specified region.", - // "httpMethod": "GET", - // "id": "compute.addresses.list", - // "parameterOrder": [ - // "project", - // "region" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the region scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}/addresses", - // "response": { - // "$ref": "AddressList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.backendServices.delete": - -type BackendServicesDeleteCall struct { - s *Service - project string - backendService string - opt_ map[string]interface{} -} - -// Delete: Deletes the specified BackendService resource. -func (r *BackendServicesService) Delete(project string, backendService string) *BackendServicesDeleteCall { - c := &BackendServicesDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.backendService = backendService - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *BackendServicesDeleteCall) Fields(s ...googleapi.Field) *BackendServicesDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *BackendServicesDeleteCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendServices/{backendService}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("DELETE", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "backendService": c.backendService, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Deletes the specified BackendService resource.", - // "httpMethod": "DELETE", - // "id": "compute.backendServices.delete", - // "parameterOrder": [ - // "project", - // "backendService" - // ], - // "parameters": { - // "backendService": { - // "description": "Name of the BackendService resource to delete.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/backendServices/{backendService}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.backendServices.get": - -type BackendServicesGetCall struct { - s *Service - project string - backendService string - opt_ map[string]interface{} -} - -// Get: Returns the specified BackendService resource. -func (r *BackendServicesService) Get(project string, backendService string) *BackendServicesGetCall { - c := &BackendServicesGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.backendService = backendService - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *BackendServicesGetCall) Fields(s ...googleapi.Field) *BackendServicesGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *BackendServicesGetCall) Do() (*BackendService, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendServices/{backendService}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "backendService": c.backendService, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *BackendService - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified BackendService resource.", - // "httpMethod": "GET", - // "id": "compute.backendServices.get", - // "parameterOrder": [ - // "project", - // "backendService" - // ], - // "parameters": { - // "backendService": { - // "description": "Name of the BackendService resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/backendServices/{backendService}", - // "response": { - // "$ref": "BackendService" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.backendServices.getHealth": - -type BackendServicesGetHealthCall struct { - s *Service - project string - backendService string - resourcegroupreference *ResourceGroupReference - opt_ map[string]interface{} -} - -// GetHealth: Gets the most recent health check results for this -// BackendService. -func (r *BackendServicesService) GetHealth(project string, backendService string, resourcegroupreference *ResourceGroupReference) *BackendServicesGetHealthCall { - c := &BackendServicesGetHealthCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.backendService = backendService - c.resourcegroupreference = resourcegroupreference - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *BackendServicesGetHealthCall) Fields(s ...googleapi.Field) *BackendServicesGetHealthCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *BackendServicesGetHealthCall) Do() (*BackendServiceGroupHealth, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.resourcegroupreference) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendServices/{backendService}/getHealth") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "backendService": c.backendService, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *BackendServiceGroupHealth - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Gets the most recent health check results for this BackendService.", - // "httpMethod": "POST", - // "id": "compute.backendServices.getHealth", - // "parameterOrder": [ - // "project", - // "backendService" - // ], - // "parameters": { - // "backendService": { - // "description": "Name of the BackendService resource to which the queried instance belongs.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/backendServices/{backendService}/getHealth", - // "request": { - // "$ref": "ResourceGroupReference" - // }, - // "response": { - // "$ref": "BackendServiceGroupHealth" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.backendServices.insert": - -type BackendServicesInsertCall struct { - s *Service - project string - backendservice *BackendService - opt_ map[string]interface{} -} - -// Insert: Creates a BackendService resource in the specified project -// using the data included in the request. -func (r *BackendServicesService) Insert(project string, backendservice *BackendService) *BackendServicesInsertCall { - c := &BackendServicesInsertCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.backendservice = backendservice - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *BackendServicesInsertCall) Fields(s ...googleapi.Field) *BackendServicesInsertCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *BackendServicesInsertCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.backendservice) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendServices") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Creates a BackendService resource in the specified project using the data included in the request.", - // "httpMethod": "POST", - // "id": "compute.backendServices.insert", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/backendServices", - // "request": { - // "$ref": "BackendService" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.backendServices.list": - -type BackendServicesListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// List: Retrieves the list of BackendService resources available to the -// specified project. -func (r *BackendServicesService) List(project string) *BackendServicesListCall { - c := &BackendServicesListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *BackendServicesListCall) Filter(filter string) *BackendServicesListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *BackendServicesListCall) MaxResults(maxResults int64) *BackendServicesListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *BackendServicesListCall) PageToken(pageToken string) *BackendServicesListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *BackendServicesListCall) Fields(s ...googleapi.Field) *BackendServicesListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *BackendServicesListCall) Do() (*BackendServiceList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendServices") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *BackendServiceList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of BackendService resources available to the specified project.", - // "httpMethod": "GET", - // "id": "compute.backendServices.list", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/backendServices", - // "response": { - // "$ref": "BackendServiceList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.backendServices.patch": - -type BackendServicesPatchCall struct { - s *Service - project string - backendService string - backendservice *BackendService - opt_ map[string]interface{} -} - -// Patch: Update the entire content of the BackendService resource. This -// method supports patch semantics. -func (r *BackendServicesService) Patch(project string, backendService string, backendservice *BackendService) *BackendServicesPatchCall { - c := &BackendServicesPatchCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.backendService = backendService - c.backendservice = backendservice - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *BackendServicesPatchCall) Fields(s ...googleapi.Field) *BackendServicesPatchCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *BackendServicesPatchCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.backendservice) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendServices/{backendService}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("PATCH", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "backendService": c.backendService, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Update the entire content of the BackendService resource. This method supports patch semantics.", - // "httpMethod": "PATCH", - // "id": "compute.backendServices.patch", - // "parameterOrder": [ - // "project", - // "backendService" - // ], - // "parameters": { - // "backendService": { - // "description": "Name of the BackendService resource to update.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/backendServices/{backendService}", - // "request": { - // "$ref": "BackendService" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.backendServices.update": - -type BackendServicesUpdateCall struct { - s *Service - project string - backendService string - backendservice *BackendService - opt_ map[string]interface{} -} - -// Update: Update the entire content of the BackendService resource. -func (r *BackendServicesService) Update(project string, backendService string, backendservice *BackendService) *BackendServicesUpdateCall { - c := &BackendServicesUpdateCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.backendService = backendService - c.backendservice = backendservice - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *BackendServicesUpdateCall) Fields(s ...googleapi.Field) *BackendServicesUpdateCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *BackendServicesUpdateCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.backendservice) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/backendServices/{backendService}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("PUT", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "backendService": c.backendService, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Update the entire content of the BackendService resource.", - // "httpMethod": "PUT", - // "id": "compute.backendServices.update", - // "parameterOrder": [ - // "project", - // "backendService" - // ], - // "parameters": { - // "backendService": { - // "description": "Name of the BackendService resource to update.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/backendServices/{backendService}", - // "request": { - // "$ref": "BackendService" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.diskTypes.aggregatedList": - -type DiskTypesAggregatedListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// AggregatedList: Retrieves the list of disk type resources grouped by -// scope. -func (r *DiskTypesService) AggregatedList(project string) *DiskTypesAggregatedListCall { - c := &DiskTypesAggregatedListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *DiskTypesAggregatedListCall) Filter(filter string) *DiskTypesAggregatedListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *DiskTypesAggregatedListCall) MaxResults(maxResults int64) *DiskTypesAggregatedListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *DiskTypesAggregatedListCall) PageToken(pageToken string) *DiskTypesAggregatedListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *DiskTypesAggregatedListCall) Fields(s ...googleapi.Field) *DiskTypesAggregatedListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *DiskTypesAggregatedListCall) Do() (*DiskTypeAggregatedList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/diskTypes") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *DiskTypeAggregatedList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of disk type resources grouped by scope.", - // "httpMethod": "GET", - // "id": "compute.diskTypes.aggregatedList", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/aggregated/diskTypes", - // "response": { - // "$ref": "DiskTypeAggregatedList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.diskTypes.get": - -type DiskTypesGetCall struct { - s *Service - project string - zone string - diskType string - opt_ map[string]interface{} -} - -// Get: Returns the specified disk type resource. -func (r *DiskTypesService) Get(project string, zone string, diskType string) *DiskTypesGetCall { - c := &DiskTypesGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.diskType = diskType - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *DiskTypesGetCall) Fields(s ...googleapi.Field) *DiskTypesGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *DiskTypesGetCall) Do() (*DiskType, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/diskTypes/{diskType}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - "diskType": c.diskType, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *DiskType - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified disk type resource.", - // "httpMethod": "GET", - // "id": "compute.diskTypes.get", - // "parameterOrder": [ - // "project", - // "zone", - // "diskType" - // ], - // "parameters": { - // "diskType": { - // "description": "Name of the disk type resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/diskTypes/{diskType}", - // "response": { - // "$ref": "DiskType" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.diskTypes.list": - -type DiskTypesListCall struct { - s *Service - project string - zone string - opt_ map[string]interface{} -} - -// List: Retrieves the list of disk type resources available to the -// specified project. -func (r *DiskTypesService) List(project string, zone string) *DiskTypesListCall { - c := &DiskTypesListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *DiskTypesListCall) Filter(filter string) *DiskTypesListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *DiskTypesListCall) MaxResults(maxResults int64) *DiskTypesListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *DiskTypesListCall) PageToken(pageToken string) *DiskTypesListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *DiskTypesListCall) Fields(s ...googleapi.Field) *DiskTypesListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *DiskTypesListCall) Do() (*DiskTypeList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/diskTypes") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *DiskTypeList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of disk type resources available to the specified project.", - // "httpMethod": "GET", - // "id": "compute.diskTypes.list", - // "parameterOrder": [ - // "project", - // "zone" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/diskTypes", - // "response": { - // "$ref": "DiskTypeList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.disks.aggregatedList": - -type DisksAggregatedListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// AggregatedList: Retrieves the list of disks grouped by scope. -func (r *DisksService) AggregatedList(project string) *DisksAggregatedListCall { - c := &DisksAggregatedListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *DisksAggregatedListCall) Filter(filter string) *DisksAggregatedListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *DisksAggregatedListCall) MaxResults(maxResults int64) *DisksAggregatedListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *DisksAggregatedListCall) PageToken(pageToken string) *DisksAggregatedListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *DisksAggregatedListCall) Fields(s ...googleapi.Field) *DisksAggregatedListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *DisksAggregatedListCall) Do() (*DiskAggregatedList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/disks") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *DiskAggregatedList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of disks grouped by scope.", - // "httpMethod": "GET", - // "id": "compute.disks.aggregatedList", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/aggregated/disks", - // "response": { - // "$ref": "DiskAggregatedList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.disks.createSnapshot": - -type DisksCreateSnapshotCall struct { - s *Service - project string - zone string - disk string - snapshot *Snapshot - opt_ map[string]interface{} -} - -// CreateSnapshot: -func (r *DisksService) CreateSnapshot(project string, zone string, disk string, snapshot *Snapshot) *DisksCreateSnapshotCall { - c := &DisksCreateSnapshotCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.disk = disk - c.snapshot = snapshot - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *DisksCreateSnapshotCall) Fields(s ...googleapi.Field) *DisksCreateSnapshotCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *DisksCreateSnapshotCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.snapshot) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/disks/{disk}/createSnapshot") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - "disk": c.disk, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "httpMethod": "POST", - // "id": "compute.disks.createSnapshot", - // "parameterOrder": [ - // "project", - // "zone", - // "disk" - // ], - // "parameters": { - // "disk": { - // "description": "Name of the persistent disk resource to snapshot.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/disks/{disk}/createSnapshot", - // "request": { - // "$ref": "Snapshot" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.disks.delete": - -type DisksDeleteCall struct { - s *Service - project string - zone string - disk string - opt_ map[string]interface{} -} - -// Delete: Deletes the specified persistent disk resource. -func (r *DisksService) Delete(project string, zone string, disk string) *DisksDeleteCall { - c := &DisksDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.disk = disk - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *DisksDeleteCall) Fields(s ...googleapi.Field) *DisksDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *DisksDeleteCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/disks/{disk}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("DELETE", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - "disk": c.disk, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Deletes the specified persistent disk resource.", - // "httpMethod": "DELETE", - // "id": "compute.disks.delete", - // "parameterOrder": [ - // "project", - // "zone", - // "disk" - // ], - // "parameters": { - // "disk": { - // "description": "Name of the persistent disk resource to delete.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/disks/{disk}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.disks.get": - -type DisksGetCall struct { - s *Service - project string - zone string - disk string - opt_ map[string]interface{} -} - -// Get: Returns the specified persistent disk resource. -func (r *DisksService) Get(project string, zone string, disk string) *DisksGetCall { - c := &DisksGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.disk = disk - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *DisksGetCall) Fields(s ...googleapi.Field) *DisksGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *DisksGetCall) Do() (*Disk, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/disks/{disk}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - "disk": c.disk, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Disk - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified persistent disk resource.", - // "httpMethod": "GET", - // "id": "compute.disks.get", - // "parameterOrder": [ - // "project", - // "zone", - // "disk" - // ], - // "parameters": { - // "disk": { - // "description": "Name of the persistent disk resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/disks/{disk}", - // "response": { - // "$ref": "Disk" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.disks.insert": - -type DisksInsertCall struct { - s *Service - project string - zone string - disk *Disk - opt_ map[string]interface{} -} - -// Insert: Creates a persistent disk resource in the specified project -// using the data included in the request. -func (r *DisksService) Insert(project string, zone string, disk *Disk) *DisksInsertCall { - c := &DisksInsertCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.disk = disk - return c -} - -// SourceImage sets the optional parameter "sourceImage": Source image -// to restore onto a disk. -func (c *DisksInsertCall) SourceImage(sourceImage string) *DisksInsertCall { - c.opt_["sourceImage"] = sourceImage - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *DisksInsertCall) Fields(s ...googleapi.Field) *DisksInsertCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *DisksInsertCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.disk) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["sourceImage"]; ok { - params.Set("sourceImage", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/disks") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Creates a persistent disk resource in the specified project using the data included in the request.", - // "httpMethod": "POST", - // "id": "compute.disks.insert", - // "parameterOrder": [ - // "project", - // "zone" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "sourceImage": { - // "description": "Optional. Source image to restore onto a disk.", - // "location": "query", - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/disks", - // "request": { - // "$ref": "Disk" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.disks.list": - -type DisksListCall struct { - s *Service - project string - zone string - opt_ map[string]interface{} -} - -// List: Retrieves the list of persistent disk resources contained -// within the specified zone. -func (r *DisksService) List(project string, zone string) *DisksListCall { - c := &DisksListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *DisksListCall) Filter(filter string) *DisksListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *DisksListCall) MaxResults(maxResults int64) *DisksListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *DisksListCall) PageToken(pageToken string) *DisksListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *DisksListCall) Fields(s ...googleapi.Field) *DisksListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *DisksListCall) Do() (*DiskList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/disks") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *DiskList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of persistent disk resources contained within the specified zone.", - // "httpMethod": "GET", - // "id": "compute.disks.list", - // "parameterOrder": [ - // "project", - // "zone" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/disks", - // "response": { - // "$ref": "DiskList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.firewalls.delete": - -type FirewallsDeleteCall struct { - s *Service - project string - firewall string - opt_ map[string]interface{} -} - -// Delete: Deletes the specified firewall resource. -func (r *FirewallsService) Delete(project string, firewall string) *FirewallsDeleteCall { - c := &FirewallsDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.firewall = firewall - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *FirewallsDeleteCall) Fields(s ...googleapi.Field) *FirewallsDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *FirewallsDeleteCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/firewalls/{firewall}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("DELETE", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "firewall": c.firewall, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Deletes the specified firewall resource.", - // "httpMethod": "DELETE", - // "id": "compute.firewalls.delete", - // "parameterOrder": [ - // "project", - // "firewall" - // ], - // "parameters": { - // "firewall": { - // "description": "Name of the firewall resource to delete.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/firewalls/{firewall}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.firewalls.get": - -type FirewallsGetCall struct { - s *Service - project string - firewall string - opt_ map[string]interface{} -} - -// Get: Returns the specified firewall resource. -func (r *FirewallsService) Get(project string, firewall string) *FirewallsGetCall { - c := &FirewallsGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.firewall = firewall - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *FirewallsGetCall) Fields(s ...googleapi.Field) *FirewallsGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *FirewallsGetCall) Do() (*Firewall, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/firewalls/{firewall}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "firewall": c.firewall, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Firewall - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified firewall resource.", - // "httpMethod": "GET", - // "id": "compute.firewalls.get", - // "parameterOrder": [ - // "project", - // "firewall" - // ], - // "parameters": { - // "firewall": { - // "description": "Name of the firewall resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/firewalls/{firewall}", - // "response": { - // "$ref": "Firewall" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.firewalls.insert": - -type FirewallsInsertCall struct { - s *Service - project string - firewall *Firewall - opt_ map[string]interface{} -} - -// Insert: Creates a firewall resource in the specified project using -// the data included in the request. -func (r *FirewallsService) Insert(project string, firewall *Firewall) *FirewallsInsertCall { - c := &FirewallsInsertCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.firewall = firewall - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *FirewallsInsertCall) Fields(s ...googleapi.Field) *FirewallsInsertCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *FirewallsInsertCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.firewall) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/firewalls") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Creates a firewall resource in the specified project using the data included in the request.", - // "httpMethod": "POST", - // "id": "compute.firewalls.insert", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/firewalls", - // "request": { - // "$ref": "Firewall" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.firewalls.list": - -type FirewallsListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// List: Retrieves the list of firewall resources available to the -// specified project. -func (r *FirewallsService) List(project string) *FirewallsListCall { - c := &FirewallsListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *FirewallsListCall) Filter(filter string) *FirewallsListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *FirewallsListCall) MaxResults(maxResults int64) *FirewallsListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *FirewallsListCall) PageToken(pageToken string) *FirewallsListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *FirewallsListCall) Fields(s ...googleapi.Field) *FirewallsListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *FirewallsListCall) Do() (*FirewallList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/firewalls") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *FirewallList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of firewall resources available to the specified project.", - // "httpMethod": "GET", - // "id": "compute.firewalls.list", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/firewalls", - // "response": { - // "$ref": "FirewallList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.firewalls.patch": - -type FirewallsPatchCall struct { - s *Service - project string - firewall string - firewall2 *Firewall - opt_ map[string]interface{} -} - -// Patch: Updates the specified firewall resource with the data included -// in the request. This method supports patch semantics. -func (r *FirewallsService) Patch(project string, firewall string, firewall2 *Firewall) *FirewallsPatchCall { - c := &FirewallsPatchCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.firewall = firewall - c.firewall2 = firewall2 - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *FirewallsPatchCall) Fields(s ...googleapi.Field) *FirewallsPatchCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *FirewallsPatchCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.firewall2) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/firewalls/{firewall}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("PATCH", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "firewall": c.firewall, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Updates the specified firewall resource with the data included in the request. This method supports patch semantics.", - // "httpMethod": "PATCH", - // "id": "compute.firewalls.patch", - // "parameterOrder": [ - // "project", - // "firewall" - // ], - // "parameters": { - // "firewall": { - // "description": "Name of the firewall resource to update.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/firewalls/{firewall}", - // "request": { - // "$ref": "Firewall" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.firewalls.update": - -type FirewallsUpdateCall struct { - s *Service - project string - firewall string - firewall2 *Firewall - opt_ map[string]interface{} -} - -// Update: Updates the specified firewall resource with the data -// included in the request. -func (r *FirewallsService) Update(project string, firewall string, firewall2 *Firewall) *FirewallsUpdateCall { - c := &FirewallsUpdateCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.firewall = firewall - c.firewall2 = firewall2 - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *FirewallsUpdateCall) Fields(s ...googleapi.Field) *FirewallsUpdateCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *FirewallsUpdateCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.firewall2) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/firewalls/{firewall}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("PUT", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "firewall": c.firewall, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Updates the specified firewall resource with the data included in the request.", - // "httpMethod": "PUT", - // "id": "compute.firewalls.update", - // "parameterOrder": [ - // "project", - // "firewall" - // ], - // "parameters": { - // "firewall": { - // "description": "Name of the firewall resource to update.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/firewalls/{firewall}", - // "request": { - // "$ref": "Firewall" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.forwardingRules.aggregatedList": - -type ForwardingRulesAggregatedListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// AggregatedList: Retrieves the list of forwarding rules grouped by -// scope. -func (r *ForwardingRulesService) AggregatedList(project string) *ForwardingRulesAggregatedListCall { - c := &ForwardingRulesAggregatedListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *ForwardingRulesAggregatedListCall) Filter(filter string) *ForwardingRulesAggregatedListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *ForwardingRulesAggregatedListCall) MaxResults(maxResults int64) *ForwardingRulesAggregatedListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *ForwardingRulesAggregatedListCall) PageToken(pageToken string) *ForwardingRulesAggregatedListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ForwardingRulesAggregatedListCall) Fields(s ...googleapi.Field) *ForwardingRulesAggregatedListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ForwardingRulesAggregatedListCall) Do() (*ForwardingRuleAggregatedList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/forwardingRules") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *ForwardingRuleAggregatedList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of forwarding rules grouped by scope.", - // "httpMethod": "GET", - // "id": "compute.forwardingRules.aggregatedList", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/aggregated/forwardingRules", - // "response": { - // "$ref": "ForwardingRuleAggregatedList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.forwardingRules.delete": - -type ForwardingRulesDeleteCall struct { - s *Service - project string - region string - forwardingRule string - opt_ map[string]interface{} -} - -// Delete: Deletes the specified ForwardingRule resource. -func (r *ForwardingRulesService) Delete(project string, region string, forwardingRule string) *ForwardingRulesDeleteCall { - c := &ForwardingRulesDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - c.forwardingRule = forwardingRule - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ForwardingRulesDeleteCall) Fields(s ...googleapi.Field) *ForwardingRulesDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ForwardingRulesDeleteCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/forwardingRules/{forwardingRule}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("DELETE", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - "forwardingRule": c.forwardingRule, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Deletes the specified ForwardingRule resource.", - // "httpMethod": "DELETE", - // "id": "compute.forwardingRules.delete", - // "parameterOrder": [ - // "project", - // "region", - // "forwardingRule" - // ], - // "parameters": { - // "forwardingRule": { - // "description": "Name of the ForwardingRule resource to delete.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the region scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}/forwardingRules/{forwardingRule}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.forwardingRules.get": - -type ForwardingRulesGetCall struct { - s *Service - project string - region string - forwardingRule string - opt_ map[string]interface{} -} - -// Get: Returns the specified ForwardingRule resource. -func (r *ForwardingRulesService) Get(project string, region string, forwardingRule string) *ForwardingRulesGetCall { - c := &ForwardingRulesGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - c.forwardingRule = forwardingRule - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ForwardingRulesGetCall) Fields(s ...googleapi.Field) *ForwardingRulesGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ForwardingRulesGetCall) Do() (*ForwardingRule, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/forwardingRules/{forwardingRule}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - "forwardingRule": c.forwardingRule, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *ForwardingRule - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified ForwardingRule resource.", - // "httpMethod": "GET", - // "id": "compute.forwardingRules.get", - // "parameterOrder": [ - // "project", - // "region", - // "forwardingRule" - // ], - // "parameters": { - // "forwardingRule": { - // "description": "Name of the ForwardingRule resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the region scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}/forwardingRules/{forwardingRule}", - // "response": { - // "$ref": "ForwardingRule" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.forwardingRules.insert": - -type ForwardingRulesInsertCall struct { - s *Service - project string - region string - forwardingrule *ForwardingRule - opt_ map[string]interface{} -} - -// Insert: Creates a ForwardingRule resource in the specified project -// and region using the data included in the request. -func (r *ForwardingRulesService) Insert(project string, region string, forwardingrule *ForwardingRule) *ForwardingRulesInsertCall { - c := &ForwardingRulesInsertCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - c.forwardingrule = forwardingrule - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ForwardingRulesInsertCall) Fields(s ...googleapi.Field) *ForwardingRulesInsertCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ForwardingRulesInsertCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.forwardingrule) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/forwardingRules") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Creates a ForwardingRule resource in the specified project and region using the data included in the request.", - // "httpMethod": "POST", - // "id": "compute.forwardingRules.insert", - // "parameterOrder": [ - // "project", - // "region" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the region scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}/forwardingRules", - // "request": { - // "$ref": "ForwardingRule" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.forwardingRules.list": - -type ForwardingRulesListCall struct { - s *Service - project string - region string - opt_ map[string]interface{} -} - -// List: Retrieves the list of ForwardingRule resources available to the -// specified project and region. -func (r *ForwardingRulesService) List(project string, region string) *ForwardingRulesListCall { - c := &ForwardingRulesListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *ForwardingRulesListCall) Filter(filter string) *ForwardingRulesListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *ForwardingRulesListCall) MaxResults(maxResults int64) *ForwardingRulesListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *ForwardingRulesListCall) PageToken(pageToken string) *ForwardingRulesListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ForwardingRulesListCall) Fields(s ...googleapi.Field) *ForwardingRulesListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ForwardingRulesListCall) Do() (*ForwardingRuleList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/forwardingRules") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *ForwardingRuleList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of ForwardingRule resources available to the specified project and region.", - // "httpMethod": "GET", - // "id": "compute.forwardingRules.list", - // "parameterOrder": [ - // "project", - // "region" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the region scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}/forwardingRules", - // "response": { - // "$ref": "ForwardingRuleList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.forwardingRules.setTarget": - -type ForwardingRulesSetTargetCall struct { - s *Service - project string - region string - forwardingRule string - targetreference *TargetReference - opt_ map[string]interface{} -} - -// SetTarget: Changes target url for forwarding rule. -func (r *ForwardingRulesService) SetTarget(project string, region string, forwardingRule string, targetreference *TargetReference) *ForwardingRulesSetTargetCall { - c := &ForwardingRulesSetTargetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - c.forwardingRule = forwardingRule - c.targetreference = targetreference - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ForwardingRulesSetTargetCall) Fields(s ...googleapi.Field) *ForwardingRulesSetTargetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ForwardingRulesSetTargetCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetreference) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/forwardingRules/{forwardingRule}/setTarget") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - "forwardingRule": c.forwardingRule, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Changes target url for forwarding rule.", - // "httpMethod": "POST", - // "id": "compute.forwardingRules.setTarget", - // "parameterOrder": [ - // "project", - // "region", - // "forwardingRule" - // ], - // "parameters": { - // "forwardingRule": { - // "description": "Name of the ForwardingRule resource in which target is to be set.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the region scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}/forwardingRules/{forwardingRule}/setTarget", - // "request": { - // "$ref": "TargetReference" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.globalAddresses.delete": - -type GlobalAddressesDeleteCall struct { - s *Service - project string - address string - opt_ map[string]interface{} -} - -// Delete: Deletes the specified address resource. -func (r *GlobalAddressesService) Delete(project string, address string) *GlobalAddressesDeleteCall { - c := &GlobalAddressesDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.address = address - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *GlobalAddressesDeleteCall) Fields(s ...googleapi.Field) *GlobalAddressesDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *GlobalAddressesDeleteCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/addresses/{address}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("DELETE", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "address": c.address, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Deletes the specified address resource.", - // "httpMethod": "DELETE", - // "id": "compute.globalAddresses.delete", - // "parameterOrder": [ - // "project", - // "address" - // ], - // "parameters": { - // "address": { - // "description": "Name of the address resource to delete.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/addresses/{address}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.globalAddresses.get": - -type GlobalAddressesGetCall struct { - s *Service - project string - address string - opt_ map[string]interface{} -} - -// Get: Returns the specified address resource. -func (r *GlobalAddressesService) Get(project string, address string) *GlobalAddressesGetCall { - c := &GlobalAddressesGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.address = address - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *GlobalAddressesGetCall) Fields(s ...googleapi.Field) *GlobalAddressesGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *GlobalAddressesGetCall) Do() (*Address, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/addresses/{address}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "address": c.address, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Address - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified address resource.", - // "httpMethod": "GET", - // "id": "compute.globalAddresses.get", - // "parameterOrder": [ - // "project", - // "address" - // ], - // "parameters": { - // "address": { - // "description": "Name of the address resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/addresses/{address}", - // "response": { - // "$ref": "Address" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.globalAddresses.insert": - -type GlobalAddressesInsertCall struct { - s *Service - project string - address *Address - opt_ map[string]interface{} -} - -// Insert: Creates an address resource in the specified project using -// the data included in the request. -func (r *GlobalAddressesService) Insert(project string, address *Address) *GlobalAddressesInsertCall { - c := &GlobalAddressesInsertCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.address = address - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *GlobalAddressesInsertCall) Fields(s ...googleapi.Field) *GlobalAddressesInsertCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *GlobalAddressesInsertCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.address) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/addresses") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Creates an address resource in the specified project using the data included in the request.", - // "httpMethod": "POST", - // "id": "compute.globalAddresses.insert", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/addresses", - // "request": { - // "$ref": "Address" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.globalAddresses.list": - -type GlobalAddressesListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// List: Retrieves the list of global address resources. -func (r *GlobalAddressesService) List(project string) *GlobalAddressesListCall { - c := &GlobalAddressesListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *GlobalAddressesListCall) Filter(filter string) *GlobalAddressesListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *GlobalAddressesListCall) MaxResults(maxResults int64) *GlobalAddressesListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *GlobalAddressesListCall) PageToken(pageToken string) *GlobalAddressesListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *GlobalAddressesListCall) Fields(s ...googleapi.Field) *GlobalAddressesListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *GlobalAddressesListCall) Do() (*AddressList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/addresses") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *AddressList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of global address resources.", - // "httpMethod": "GET", - // "id": "compute.globalAddresses.list", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/addresses", - // "response": { - // "$ref": "AddressList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.globalForwardingRules.delete": - -type GlobalForwardingRulesDeleteCall struct { - s *Service - project string - forwardingRule string - opt_ map[string]interface{} -} - -// Delete: Deletes the specified ForwardingRule resource. -func (r *GlobalForwardingRulesService) Delete(project string, forwardingRule string) *GlobalForwardingRulesDeleteCall { - c := &GlobalForwardingRulesDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.forwardingRule = forwardingRule - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *GlobalForwardingRulesDeleteCall) Fields(s ...googleapi.Field) *GlobalForwardingRulesDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *GlobalForwardingRulesDeleteCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/forwardingRules/{forwardingRule}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("DELETE", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "forwardingRule": c.forwardingRule, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Deletes the specified ForwardingRule resource.", - // "httpMethod": "DELETE", - // "id": "compute.globalForwardingRules.delete", - // "parameterOrder": [ - // "project", - // "forwardingRule" - // ], - // "parameters": { - // "forwardingRule": { - // "description": "Name of the ForwardingRule resource to delete.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/forwardingRules/{forwardingRule}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.globalForwardingRules.get": - -type GlobalForwardingRulesGetCall struct { - s *Service - project string - forwardingRule string - opt_ map[string]interface{} -} - -// Get: Returns the specified ForwardingRule resource. -func (r *GlobalForwardingRulesService) Get(project string, forwardingRule string) *GlobalForwardingRulesGetCall { - c := &GlobalForwardingRulesGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.forwardingRule = forwardingRule - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *GlobalForwardingRulesGetCall) Fields(s ...googleapi.Field) *GlobalForwardingRulesGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *GlobalForwardingRulesGetCall) Do() (*ForwardingRule, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/forwardingRules/{forwardingRule}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "forwardingRule": c.forwardingRule, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *ForwardingRule - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified ForwardingRule resource.", - // "httpMethod": "GET", - // "id": "compute.globalForwardingRules.get", - // "parameterOrder": [ - // "project", - // "forwardingRule" - // ], - // "parameters": { - // "forwardingRule": { - // "description": "Name of the ForwardingRule resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/forwardingRules/{forwardingRule}", - // "response": { - // "$ref": "ForwardingRule" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.globalForwardingRules.insert": - -type GlobalForwardingRulesInsertCall struct { - s *Service - project string - forwardingrule *ForwardingRule - opt_ map[string]interface{} -} - -// Insert: Creates a ForwardingRule resource in the specified project -// and region using the data included in the request. -func (r *GlobalForwardingRulesService) Insert(project string, forwardingrule *ForwardingRule) *GlobalForwardingRulesInsertCall { - c := &GlobalForwardingRulesInsertCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.forwardingrule = forwardingrule - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *GlobalForwardingRulesInsertCall) Fields(s ...googleapi.Field) *GlobalForwardingRulesInsertCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *GlobalForwardingRulesInsertCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.forwardingrule) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/forwardingRules") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Creates a ForwardingRule resource in the specified project and region using the data included in the request.", - // "httpMethod": "POST", - // "id": "compute.globalForwardingRules.insert", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/forwardingRules", - // "request": { - // "$ref": "ForwardingRule" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.globalForwardingRules.list": - -type GlobalForwardingRulesListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// List: Retrieves the list of ForwardingRule resources available to the -// specified project. -func (r *GlobalForwardingRulesService) List(project string) *GlobalForwardingRulesListCall { - c := &GlobalForwardingRulesListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *GlobalForwardingRulesListCall) Filter(filter string) *GlobalForwardingRulesListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *GlobalForwardingRulesListCall) MaxResults(maxResults int64) *GlobalForwardingRulesListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *GlobalForwardingRulesListCall) PageToken(pageToken string) *GlobalForwardingRulesListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *GlobalForwardingRulesListCall) Fields(s ...googleapi.Field) *GlobalForwardingRulesListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *GlobalForwardingRulesListCall) Do() (*ForwardingRuleList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/forwardingRules") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *ForwardingRuleList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of ForwardingRule resources available to the specified project.", - // "httpMethod": "GET", - // "id": "compute.globalForwardingRules.list", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/forwardingRules", - // "response": { - // "$ref": "ForwardingRuleList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.globalForwardingRules.setTarget": - -type GlobalForwardingRulesSetTargetCall struct { - s *Service - project string - forwardingRule string - targetreference *TargetReference - opt_ map[string]interface{} -} - -// SetTarget: Changes target url for forwarding rule. -func (r *GlobalForwardingRulesService) SetTarget(project string, forwardingRule string, targetreference *TargetReference) *GlobalForwardingRulesSetTargetCall { - c := &GlobalForwardingRulesSetTargetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.forwardingRule = forwardingRule - c.targetreference = targetreference - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *GlobalForwardingRulesSetTargetCall) Fields(s ...googleapi.Field) *GlobalForwardingRulesSetTargetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *GlobalForwardingRulesSetTargetCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetreference) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/forwardingRules/{forwardingRule}/setTarget") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "forwardingRule": c.forwardingRule, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Changes target url for forwarding rule.", - // "httpMethod": "POST", - // "id": "compute.globalForwardingRules.setTarget", - // "parameterOrder": [ - // "project", - // "forwardingRule" - // ], - // "parameters": { - // "forwardingRule": { - // "description": "Name of the ForwardingRule resource in which target is to be set.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/forwardingRules/{forwardingRule}/setTarget", - // "request": { - // "$ref": "TargetReference" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.globalOperations.aggregatedList": - -type GlobalOperationsAggregatedListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// AggregatedList: Retrieves the list of all operations grouped by -// scope. -func (r *GlobalOperationsService) AggregatedList(project string) *GlobalOperationsAggregatedListCall { - c := &GlobalOperationsAggregatedListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *GlobalOperationsAggregatedListCall) Filter(filter string) *GlobalOperationsAggregatedListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *GlobalOperationsAggregatedListCall) MaxResults(maxResults int64) *GlobalOperationsAggregatedListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *GlobalOperationsAggregatedListCall) PageToken(pageToken string) *GlobalOperationsAggregatedListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *GlobalOperationsAggregatedListCall) Fields(s ...googleapi.Field) *GlobalOperationsAggregatedListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *GlobalOperationsAggregatedListCall) Do() (*OperationAggregatedList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/operations") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *OperationAggregatedList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of all operations grouped by scope.", - // "httpMethod": "GET", - // "id": "compute.globalOperations.aggregatedList", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/aggregated/operations", - // "response": { - // "$ref": "OperationAggregatedList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.globalOperations.delete": - -type GlobalOperationsDeleteCall struct { - s *Service - project string - operation string - opt_ map[string]interface{} -} - -// Delete: Deletes the specified operation resource. -func (r *GlobalOperationsService) Delete(project string, operation string) *GlobalOperationsDeleteCall { - c := &GlobalOperationsDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.operation = operation - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *GlobalOperationsDeleteCall) Fields(s ...googleapi.Field) *GlobalOperationsDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *GlobalOperationsDeleteCall) Do() error { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/operations/{operation}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("DELETE", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "operation": c.operation, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return err - } - return nil - // { - // "description": "Deletes the specified operation resource.", - // "httpMethod": "DELETE", - // "id": "compute.globalOperations.delete", - // "parameterOrder": [ - // "project", - // "operation" - // ], - // "parameters": { - // "operation": { - // "description": "Name of the operation resource to delete.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/operations/{operation}", - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.globalOperations.get": - -type GlobalOperationsGetCall struct { - s *Service - project string - operation string - opt_ map[string]interface{} -} - -// Get: Retrieves the specified operation resource. -func (r *GlobalOperationsService) Get(project string, operation string) *GlobalOperationsGetCall { - c := &GlobalOperationsGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.operation = operation - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *GlobalOperationsGetCall) Fields(s ...googleapi.Field) *GlobalOperationsGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *GlobalOperationsGetCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/operations/{operation}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "operation": c.operation, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the specified operation resource.", - // "httpMethod": "GET", - // "id": "compute.globalOperations.get", - // "parameterOrder": [ - // "project", - // "operation" - // ], - // "parameters": { - // "operation": { - // "description": "Name of the operation resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/operations/{operation}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.globalOperations.list": - -type GlobalOperationsListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// List: Retrieves the list of operation resources contained within the -// specified project. -func (r *GlobalOperationsService) List(project string) *GlobalOperationsListCall { - c := &GlobalOperationsListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *GlobalOperationsListCall) Filter(filter string) *GlobalOperationsListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *GlobalOperationsListCall) MaxResults(maxResults int64) *GlobalOperationsListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *GlobalOperationsListCall) PageToken(pageToken string) *GlobalOperationsListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *GlobalOperationsListCall) Fields(s ...googleapi.Field) *GlobalOperationsListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *GlobalOperationsListCall) Do() (*OperationList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/operations") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *OperationList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of operation resources contained within the specified project.", - // "httpMethod": "GET", - // "id": "compute.globalOperations.list", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/operations", - // "response": { - // "$ref": "OperationList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.httpHealthChecks.delete": - -type HttpHealthChecksDeleteCall struct { - s *Service - project string - httpHealthCheck string - opt_ map[string]interface{} -} - -// Delete: Deletes the specified HttpHealthCheck resource. -func (r *HttpHealthChecksService) Delete(project string, httpHealthCheck string) *HttpHealthChecksDeleteCall { - c := &HttpHealthChecksDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.httpHealthCheck = httpHealthCheck - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *HttpHealthChecksDeleteCall) Fields(s ...googleapi.Field) *HttpHealthChecksDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *HttpHealthChecksDeleteCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/httpHealthChecks/{httpHealthCheck}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("DELETE", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "httpHealthCheck": c.httpHealthCheck, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Deletes the specified HttpHealthCheck resource.", - // "httpMethod": "DELETE", - // "id": "compute.httpHealthChecks.delete", - // "parameterOrder": [ - // "project", - // "httpHealthCheck" - // ], - // "parameters": { - // "httpHealthCheck": { - // "description": "Name of the HttpHealthCheck resource to delete.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/httpHealthChecks/{httpHealthCheck}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.httpHealthChecks.get": - -type HttpHealthChecksGetCall struct { - s *Service - project string - httpHealthCheck string - opt_ map[string]interface{} -} - -// Get: Returns the specified HttpHealthCheck resource. -func (r *HttpHealthChecksService) Get(project string, httpHealthCheck string) *HttpHealthChecksGetCall { - c := &HttpHealthChecksGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.httpHealthCheck = httpHealthCheck - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *HttpHealthChecksGetCall) Fields(s ...googleapi.Field) *HttpHealthChecksGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *HttpHealthChecksGetCall) Do() (*HttpHealthCheck, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/httpHealthChecks/{httpHealthCheck}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "httpHealthCheck": c.httpHealthCheck, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *HttpHealthCheck - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified HttpHealthCheck resource.", - // "httpMethod": "GET", - // "id": "compute.httpHealthChecks.get", - // "parameterOrder": [ - // "project", - // "httpHealthCheck" - // ], - // "parameters": { - // "httpHealthCheck": { - // "description": "Name of the HttpHealthCheck resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/httpHealthChecks/{httpHealthCheck}", - // "response": { - // "$ref": "HttpHealthCheck" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.httpHealthChecks.insert": - -type HttpHealthChecksInsertCall struct { - s *Service - project string - httphealthcheck *HttpHealthCheck - opt_ map[string]interface{} -} - -// Insert: Creates a HttpHealthCheck resource in the specified project -// using the data included in the request. -func (r *HttpHealthChecksService) Insert(project string, httphealthcheck *HttpHealthCheck) *HttpHealthChecksInsertCall { - c := &HttpHealthChecksInsertCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.httphealthcheck = httphealthcheck - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *HttpHealthChecksInsertCall) Fields(s ...googleapi.Field) *HttpHealthChecksInsertCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *HttpHealthChecksInsertCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.httphealthcheck) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/httpHealthChecks") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Creates a HttpHealthCheck resource in the specified project using the data included in the request.", - // "httpMethod": "POST", - // "id": "compute.httpHealthChecks.insert", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/httpHealthChecks", - // "request": { - // "$ref": "HttpHealthCheck" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.httpHealthChecks.list": - -type HttpHealthChecksListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// List: Retrieves the list of HttpHealthCheck resources available to -// the specified project. -func (r *HttpHealthChecksService) List(project string) *HttpHealthChecksListCall { - c := &HttpHealthChecksListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *HttpHealthChecksListCall) Filter(filter string) *HttpHealthChecksListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *HttpHealthChecksListCall) MaxResults(maxResults int64) *HttpHealthChecksListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *HttpHealthChecksListCall) PageToken(pageToken string) *HttpHealthChecksListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *HttpHealthChecksListCall) Fields(s ...googleapi.Field) *HttpHealthChecksListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *HttpHealthChecksListCall) Do() (*HttpHealthCheckList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/httpHealthChecks") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *HttpHealthCheckList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of HttpHealthCheck resources available to the specified project.", - // "httpMethod": "GET", - // "id": "compute.httpHealthChecks.list", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/httpHealthChecks", - // "response": { - // "$ref": "HttpHealthCheckList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.httpHealthChecks.patch": - -type HttpHealthChecksPatchCall struct { - s *Service - project string - httpHealthCheck string - httphealthcheck *HttpHealthCheck - opt_ map[string]interface{} -} - -// Patch: Updates a HttpHealthCheck resource in the specified project -// using the data included in the request. This method supports patch -// semantics. -func (r *HttpHealthChecksService) Patch(project string, httpHealthCheck string, httphealthcheck *HttpHealthCheck) *HttpHealthChecksPatchCall { - c := &HttpHealthChecksPatchCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.httpHealthCheck = httpHealthCheck - c.httphealthcheck = httphealthcheck - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *HttpHealthChecksPatchCall) Fields(s ...googleapi.Field) *HttpHealthChecksPatchCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *HttpHealthChecksPatchCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.httphealthcheck) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/httpHealthChecks/{httpHealthCheck}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("PATCH", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "httpHealthCheck": c.httpHealthCheck, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Updates a HttpHealthCheck resource in the specified project using the data included in the request. This method supports patch semantics.", - // "httpMethod": "PATCH", - // "id": "compute.httpHealthChecks.patch", - // "parameterOrder": [ - // "project", - // "httpHealthCheck" - // ], - // "parameters": { - // "httpHealthCheck": { - // "description": "Name of the HttpHealthCheck resource to update.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/httpHealthChecks/{httpHealthCheck}", - // "request": { - // "$ref": "HttpHealthCheck" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.httpHealthChecks.update": - -type HttpHealthChecksUpdateCall struct { - s *Service - project string - httpHealthCheck string - httphealthcheck *HttpHealthCheck - opt_ map[string]interface{} -} - -// Update: Updates a HttpHealthCheck resource in the specified project -// using the data included in the request. -func (r *HttpHealthChecksService) Update(project string, httpHealthCheck string, httphealthcheck *HttpHealthCheck) *HttpHealthChecksUpdateCall { - c := &HttpHealthChecksUpdateCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.httpHealthCheck = httpHealthCheck - c.httphealthcheck = httphealthcheck - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *HttpHealthChecksUpdateCall) Fields(s ...googleapi.Field) *HttpHealthChecksUpdateCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *HttpHealthChecksUpdateCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.httphealthcheck) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/httpHealthChecks/{httpHealthCheck}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("PUT", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "httpHealthCheck": c.httpHealthCheck, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Updates a HttpHealthCheck resource in the specified project using the data included in the request.", - // "httpMethod": "PUT", - // "id": "compute.httpHealthChecks.update", - // "parameterOrder": [ - // "project", - // "httpHealthCheck" - // ], - // "parameters": { - // "httpHealthCheck": { - // "description": "Name of the HttpHealthCheck resource to update.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/httpHealthChecks/{httpHealthCheck}", - // "request": { - // "$ref": "HttpHealthCheck" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.images.delete": - -type ImagesDeleteCall struct { - s *Service - project string - image string - opt_ map[string]interface{} -} - -// Delete: Deletes the specified image resource. -func (r *ImagesService) Delete(project string, image string) *ImagesDeleteCall { - c := &ImagesDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.image = image - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ImagesDeleteCall) Fields(s ...googleapi.Field) *ImagesDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ImagesDeleteCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/images/{image}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("DELETE", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "image": c.image, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Deletes the specified image resource.", - // "httpMethod": "DELETE", - // "id": "compute.images.delete", - // "parameterOrder": [ - // "project", - // "image" - // ], - // "parameters": { - // "image": { - // "description": "Name of the image resource to delete.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/images/{image}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.images.deprecate": - -type ImagesDeprecateCall struct { - s *Service - project string - image string - deprecationstatus *DeprecationStatus - opt_ map[string]interface{} -} - -// Deprecate: Sets the deprecation status of an image. If no message -// body is given, clears the deprecation status instead. -func (r *ImagesService) Deprecate(project string, image string, deprecationstatus *DeprecationStatus) *ImagesDeprecateCall { - c := &ImagesDeprecateCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.image = image - c.deprecationstatus = deprecationstatus - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ImagesDeprecateCall) Fields(s ...googleapi.Field) *ImagesDeprecateCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ImagesDeprecateCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.deprecationstatus) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/images/{image}/deprecate") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "image": c.image, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Sets the deprecation status of an image. If no message body is given, clears the deprecation status instead.", - // "httpMethod": "POST", - // "id": "compute.images.deprecate", - // "parameterOrder": [ - // "project", - // "image" - // ], - // "parameters": { - // "image": { - // "description": "Image name.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/images/{image}/deprecate", - // "request": { - // "$ref": "DeprecationStatus" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.images.get": - -type ImagesGetCall struct { - s *Service - project string - image string - opt_ map[string]interface{} -} - -// Get: Returns the specified image resource. -func (r *ImagesService) Get(project string, image string) *ImagesGetCall { - c := &ImagesGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.image = image - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ImagesGetCall) Fields(s ...googleapi.Field) *ImagesGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ImagesGetCall) Do() (*Image, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/images/{image}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "image": c.image, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Image - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified image resource.", - // "httpMethod": "GET", - // "id": "compute.images.get", - // "parameterOrder": [ - // "project", - // "image" - // ], - // "parameters": { - // "image": { - // "description": "Name of the image resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/images/{image}", - // "response": { - // "$ref": "Image" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.images.insert": - -type ImagesInsertCall struct { - s *Service - project string - image *Image - opt_ map[string]interface{} -} - -// Insert: Creates an image resource in the specified project using the -// data included in the request. -func (r *ImagesService) Insert(project string, image *Image) *ImagesInsertCall { - c := &ImagesInsertCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.image = image - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ImagesInsertCall) Fields(s ...googleapi.Field) *ImagesInsertCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ImagesInsertCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.image) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/images") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Creates an image resource in the specified project using the data included in the request.", - // "httpMethod": "POST", - // "id": "compute.images.insert", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/images", - // "request": { - // "$ref": "Image" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/devstorage.full_control", - // "https://www.googleapis.com/auth/devstorage.read_only", - // "https://www.googleapis.com/auth/devstorage.read_write" - // ] - // } - -} - -// method id "compute.images.list": - -type ImagesListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// List: Retrieves the list of image resources available to the -// specified project. -func (r *ImagesService) List(project string) *ImagesListCall { - c := &ImagesListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *ImagesListCall) Filter(filter string) *ImagesListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *ImagesListCall) MaxResults(maxResults int64) *ImagesListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *ImagesListCall) PageToken(pageToken string) *ImagesListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ImagesListCall) Fields(s ...googleapi.Field) *ImagesListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ImagesListCall) Do() (*ImageList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/images") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *ImageList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of image resources available to the specified project.", - // "httpMethod": "GET", - // "id": "compute.images.list", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/images", - // "response": { - // "$ref": "ImageList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.instanceTemplates.delete": - -type InstanceTemplatesDeleteCall struct { - s *Service - project string - instanceTemplate string - opt_ map[string]interface{} -} - -// Delete: Deletes the specified instance template resource. -func (r *InstanceTemplatesService) Delete(project string, instanceTemplate string) *InstanceTemplatesDeleteCall { - c := &InstanceTemplatesDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.instanceTemplate = instanceTemplate - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *InstanceTemplatesDeleteCall) Fields(s ...googleapi.Field) *InstanceTemplatesDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *InstanceTemplatesDeleteCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/instanceTemplates/{instanceTemplate}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("DELETE", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "instanceTemplate": c.instanceTemplate, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Deletes the specified instance template resource.", - // "httpMethod": "DELETE", - // "id": "compute.instanceTemplates.delete", - // "parameterOrder": [ - // "project", - // "instanceTemplate" - // ], - // "parameters": { - // "instanceTemplate": { - // "description": "Name of the instance template resource to delete.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/instanceTemplates/{instanceTemplate}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.instanceTemplates.get": - -type InstanceTemplatesGetCall struct { - s *Service - project string - instanceTemplate string - opt_ map[string]interface{} -} - -// Get: Returns the specified instance template resource. -func (r *InstanceTemplatesService) Get(project string, instanceTemplate string) *InstanceTemplatesGetCall { - c := &InstanceTemplatesGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.instanceTemplate = instanceTemplate - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *InstanceTemplatesGetCall) Fields(s ...googleapi.Field) *InstanceTemplatesGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *InstanceTemplatesGetCall) Do() (*InstanceTemplate, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/instanceTemplates/{instanceTemplate}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "instanceTemplate": c.instanceTemplate, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *InstanceTemplate - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified instance template resource.", - // "httpMethod": "GET", - // "id": "compute.instanceTemplates.get", - // "parameterOrder": [ - // "project", - // "instanceTemplate" - // ], - // "parameters": { - // "instanceTemplate": { - // "description": "Name of the instance template resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/instanceTemplates/{instanceTemplate}", - // "response": { - // "$ref": "InstanceTemplate" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.instanceTemplates.insert": - -type InstanceTemplatesInsertCall struct { - s *Service - project string - instancetemplate *InstanceTemplate - opt_ map[string]interface{} -} - -// Insert: Creates an instance template resource in the specified -// project using the data included in the request. -func (r *InstanceTemplatesService) Insert(project string, instancetemplate *InstanceTemplate) *InstanceTemplatesInsertCall { - c := &InstanceTemplatesInsertCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.instancetemplate = instancetemplate - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *InstanceTemplatesInsertCall) Fields(s ...googleapi.Field) *InstanceTemplatesInsertCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *InstanceTemplatesInsertCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancetemplate) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/instanceTemplates") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Creates an instance template resource in the specified project using the data included in the request.", - // "httpMethod": "POST", - // "id": "compute.instanceTemplates.insert", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/instanceTemplates", - // "request": { - // "$ref": "InstanceTemplate" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.instanceTemplates.list": - -type InstanceTemplatesListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// List: Retrieves the list of instance template resources contained -// within the specified project. -func (r *InstanceTemplatesService) List(project string) *InstanceTemplatesListCall { - c := &InstanceTemplatesListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *InstanceTemplatesListCall) Filter(filter string) *InstanceTemplatesListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *InstanceTemplatesListCall) MaxResults(maxResults int64) *InstanceTemplatesListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *InstanceTemplatesListCall) PageToken(pageToken string) *InstanceTemplatesListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *InstanceTemplatesListCall) Fields(s ...googleapi.Field) *InstanceTemplatesListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *InstanceTemplatesListCall) Do() (*InstanceTemplateList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/instanceTemplates") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *InstanceTemplateList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of instance template resources contained within the specified project.", - // "httpMethod": "GET", - // "id": "compute.instanceTemplates.list", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/instanceTemplates", - // "response": { - // "$ref": "InstanceTemplateList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.instances.addAccessConfig": - -type InstancesAddAccessConfigCall struct { - s *Service - project string - zone string - instance string - networkInterface string - accessconfig *AccessConfig - opt_ map[string]interface{} -} - -// AddAccessConfig: Adds an access config to an instance's network -// interface. -func (r *InstancesService) AddAccessConfig(project string, zone string, instance string, networkInterface string, accessconfig *AccessConfig) *InstancesAddAccessConfigCall { - c := &InstancesAddAccessConfigCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.instance = instance - c.networkInterface = networkInterface - c.accessconfig = accessconfig - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *InstancesAddAccessConfigCall) Fields(s ...googleapi.Field) *InstancesAddAccessConfigCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *InstancesAddAccessConfigCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.accessconfig) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - params.Set("networkInterface", fmt.Sprintf("%v", c.networkInterface)) - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/addAccessConfig") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - "instance": c.instance, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Adds an access config to an instance's network interface.", - // "httpMethod": "POST", - // "id": "compute.instances.addAccessConfig", - // "parameterOrder": [ - // "project", - // "zone", - // "instance", - // "networkInterface" - // ], - // "parameters": { - // "instance": { - // "description": "Instance name.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "networkInterface": { - // "description": "Network interface name.", - // "location": "query", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Project name.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/instances/{instance}/addAccessConfig", - // "request": { - // "$ref": "AccessConfig" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.instances.aggregatedList": - -type InstancesAggregatedListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// AggregatedList: -func (r *InstancesService) AggregatedList(project string) *InstancesAggregatedListCall { - c := &InstancesAggregatedListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *InstancesAggregatedListCall) Filter(filter string) *InstancesAggregatedListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *InstancesAggregatedListCall) MaxResults(maxResults int64) *InstancesAggregatedListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *InstancesAggregatedListCall) PageToken(pageToken string) *InstancesAggregatedListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *InstancesAggregatedListCall) Fields(s ...googleapi.Field) *InstancesAggregatedListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *InstancesAggregatedListCall) Do() (*InstanceAggregatedList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/instances") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *InstanceAggregatedList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "httpMethod": "GET", - // "id": "compute.instances.aggregatedList", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/aggregated/instances", - // "response": { - // "$ref": "InstanceAggregatedList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.instances.attachDisk": - -type InstancesAttachDiskCall struct { - s *Service - project string - zone string - instance string - attacheddisk *AttachedDisk - opt_ map[string]interface{} -} - -// AttachDisk: Attaches a disk resource to an instance. -func (r *InstancesService) AttachDisk(project string, zone string, instance string, attacheddisk *AttachedDisk) *InstancesAttachDiskCall { - c := &InstancesAttachDiskCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.instance = instance - c.attacheddisk = attacheddisk - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *InstancesAttachDiskCall) Fields(s ...googleapi.Field) *InstancesAttachDiskCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *InstancesAttachDiskCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.attacheddisk) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/attachDisk") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - "instance": c.instance, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Attaches a disk resource to an instance.", - // "httpMethod": "POST", - // "id": "compute.instances.attachDisk", - // "parameterOrder": [ - // "project", - // "zone", - // "instance" - // ], - // "parameters": { - // "instance": { - // "description": "Instance name.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Project name.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/instances/{instance}/attachDisk", - // "request": { - // "$ref": "AttachedDisk" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.instances.delete": - -type InstancesDeleteCall struct { - s *Service - project string - zone string - instance string - opt_ map[string]interface{} -} - -// Delete: Deletes the specified instance resource. -func (r *InstancesService) Delete(project string, zone string, instance string) *InstancesDeleteCall { - c := &InstancesDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.instance = instance - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *InstancesDeleteCall) Fields(s ...googleapi.Field) *InstancesDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *InstancesDeleteCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("DELETE", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - "instance": c.instance, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Deletes the specified instance resource.", - // "httpMethod": "DELETE", - // "id": "compute.instances.delete", - // "parameterOrder": [ - // "project", - // "zone", - // "instance" - // ], - // "parameters": { - // "instance": { - // "description": "Name of the instance resource to delete.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/instances/{instance}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.instances.deleteAccessConfig": - -type InstancesDeleteAccessConfigCall struct { - s *Service - project string - zone string - instance string - accessConfig string - networkInterface string - opt_ map[string]interface{} -} - -// DeleteAccessConfig: Deletes an access config from an instance's -// network interface. -func (r *InstancesService) DeleteAccessConfig(project string, zone string, instance string, accessConfig string, networkInterface string) *InstancesDeleteAccessConfigCall { - c := &InstancesDeleteAccessConfigCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.instance = instance - c.accessConfig = accessConfig - c.networkInterface = networkInterface - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *InstancesDeleteAccessConfigCall) Fields(s ...googleapi.Field) *InstancesDeleteAccessConfigCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *InstancesDeleteAccessConfigCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - params.Set("accessConfig", fmt.Sprintf("%v", c.accessConfig)) - params.Set("networkInterface", fmt.Sprintf("%v", c.networkInterface)) - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/deleteAccessConfig") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - "instance": c.instance, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Deletes an access config from an instance's network interface.", - // "httpMethod": "POST", - // "id": "compute.instances.deleteAccessConfig", - // "parameterOrder": [ - // "project", - // "zone", - // "instance", - // "accessConfig", - // "networkInterface" - // ], - // "parameters": { - // "accessConfig": { - // "description": "Access config name.", - // "location": "query", - // "required": true, - // "type": "string" - // }, - // "instance": { - // "description": "Instance name.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "networkInterface": { - // "description": "Network interface name.", - // "location": "query", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Project name.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/instances/{instance}/deleteAccessConfig", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.instances.detachDisk": - -type InstancesDetachDiskCall struct { - s *Service - project string - zone string - instance string - deviceName string - opt_ map[string]interface{} -} - -// DetachDisk: Detaches a disk from an instance. -func (r *InstancesService) DetachDisk(project string, zone string, instance string, deviceName string) *InstancesDetachDiskCall { - c := &InstancesDetachDiskCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.instance = instance - c.deviceName = deviceName - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *InstancesDetachDiskCall) Fields(s ...googleapi.Field) *InstancesDetachDiskCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *InstancesDetachDiskCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - params.Set("deviceName", fmt.Sprintf("%v", c.deviceName)) - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/detachDisk") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - "instance": c.instance, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Detaches a disk from an instance.", - // "httpMethod": "POST", - // "id": "compute.instances.detachDisk", - // "parameterOrder": [ - // "project", - // "zone", - // "instance", - // "deviceName" - // ], - // "parameters": { - // "deviceName": { - // "description": "Disk device name to detach.", - // "location": "query", - // "pattern": "\\w[\\w.-]{0,254}", - // "required": true, - // "type": "string" - // }, - // "instance": { - // "description": "Instance name.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Project name.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/instances/{instance}/detachDisk", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.instances.get": - -type InstancesGetCall struct { - s *Service - project string - zone string - instance string - opt_ map[string]interface{} -} - -// Get: Returns the specified instance resource. -func (r *InstancesService) Get(project string, zone string, instance string) *InstancesGetCall { - c := &InstancesGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.instance = instance - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *InstancesGetCall) Fields(s ...googleapi.Field) *InstancesGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *InstancesGetCall) Do() (*Instance, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - "instance": c.instance, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Instance - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified instance resource.", - // "httpMethod": "GET", - // "id": "compute.instances.get", - // "parameterOrder": [ - // "project", - // "zone", - // "instance" - // ], - // "parameters": { - // "instance": { - // "description": "Name of the instance resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/instances/{instance}", - // "response": { - // "$ref": "Instance" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.instances.getSerialPortOutput": - -type InstancesGetSerialPortOutputCall struct { - s *Service - project string - zone string - instance string - opt_ map[string]interface{} -} - -// GetSerialPortOutput: Returns the specified instance's serial port -// output. -func (r *InstancesService) GetSerialPortOutput(project string, zone string, instance string) *InstancesGetSerialPortOutputCall { - c := &InstancesGetSerialPortOutputCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.instance = instance - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *InstancesGetSerialPortOutputCall) Fields(s ...googleapi.Field) *InstancesGetSerialPortOutputCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *InstancesGetSerialPortOutputCall) Do() (*SerialPortOutput, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/serialPort") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - "instance": c.instance, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *SerialPortOutput - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified instance's serial port output.", - // "httpMethod": "GET", - // "id": "compute.instances.getSerialPortOutput", - // "parameterOrder": [ - // "project", - // "zone", - // "instance" - // ], - // "parameters": { - // "instance": { - // "description": "Name of the instance scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/instances/{instance}/serialPort", - // "response": { - // "$ref": "SerialPortOutput" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.instances.insert": - -type InstancesInsertCall struct { - s *Service - project string - zone string - instance *Instance - opt_ map[string]interface{} -} - -// Insert: Creates an instance resource in the specified project using -// the data included in the request. -func (r *InstancesService) Insert(project string, zone string, instance *Instance) *InstancesInsertCall { - c := &InstancesInsertCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.instance = instance - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *InstancesInsertCall) Fields(s ...googleapi.Field) *InstancesInsertCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *InstancesInsertCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.instance) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Creates an instance resource in the specified project using the data included in the request.", - // "httpMethod": "POST", - // "id": "compute.instances.insert", - // "parameterOrder": [ - // "project", - // "zone" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/instances", - // "request": { - // "$ref": "Instance" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.instances.list": - -type InstancesListCall struct { - s *Service - project string - zone string - opt_ map[string]interface{} -} - -// List: Retrieves the list of instance resources contained within the -// specified zone. -func (r *InstancesService) List(project string, zone string) *InstancesListCall { - c := &InstancesListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *InstancesListCall) Filter(filter string) *InstancesListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *InstancesListCall) MaxResults(maxResults int64) *InstancesListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *InstancesListCall) PageToken(pageToken string) *InstancesListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *InstancesListCall) Fields(s ...googleapi.Field) *InstancesListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *InstancesListCall) Do() (*InstanceList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *InstanceList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of instance resources contained within the specified zone.", - // "httpMethod": "GET", - // "id": "compute.instances.list", - // "parameterOrder": [ - // "project", - // "zone" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/instances", - // "response": { - // "$ref": "InstanceList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.instances.reset": - -type InstancesResetCall struct { - s *Service - project string - zone string - instance string - opt_ map[string]interface{} -} - -// Reset: Performs a hard reset on the instance. -func (r *InstancesService) Reset(project string, zone string, instance string) *InstancesResetCall { - c := &InstancesResetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.instance = instance - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *InstancesResetCall) Fields(s ...googleapi.Field) *InstancesResetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *InstancesResetCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/reset") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - "instance": c.instance, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Performs a hard reset on the instance.", - // "httpMethod": "POST", - // "id": "compute.instances.reset", - // "parameterOrder": [ - // "project", - // "zone", - // "instance" - // ], - // "parameters": { - // "instance": { - // "description": "Name of the instance scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/instances/{instance}/reset", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.instances.setDiskAutoDelete": - -type InstancesSetDiskAutoDeleteCall struct { - s *Service - project string - zone string - instance string - autoDelete bool - deviceName string - opt_ map[string]interface{} -} - -// SetDiskAutoDelete: Sets the auto-delete flag for a disk attached to -// an instance -func (r *InstancesService) SetDiskAutoDelete(project string, zone string, instance string, autoDelete bool, deviceName string) *InstancesSetDiskAutoDeleteCall { - c := &InstancesSetDiskAutoDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.instance = instance - c.autoDelete = autoDelete - c.deviceName = deviceName - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *InstancesSetDiskAutoDeleteCall) Fields(s ...googleapi.Field) *InstancesSetDiskAutoDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *InstancesSetDiskAutoDeleteCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - params.Set("autoDelete", fmt.Sprintf("%v", c.autoDelete)) - params.Set("deviceName", fmt.Sprintf("%v", c.deviceName)) - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/setDiskAutoDelete") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - "instance": c.instance, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Sets the auto-delete flag for a disk attached to an instance", - // "httpMethod": "POST", - // "id": "compute.instances.setDiskAutoDelete", - // "parameterOrder": [ - // "project", - // "zone", - // "instance", - // "autoDelete", - // "deviceName" - // ], - // "parameters": { - // "autoDelete": { - // "description": "Whether to auto-delete the disk when the instance is deleted.", - // "location": "query", - // "required": true, - // "type": "boolean" - // }, - // "deviceName": { - // "description": "Disk device name to modify.", - // "location": "query", - // "pattern": "\\w[\\w.-]{0,254}", - // "required": true, - // "type": "string" - // }, - // "instance": { - // "description": "Instance name.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Project name.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/instances/{instance}/setDiskAutoDelete", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.instances.setMetadata": - -type InstancesSetMetadataCall struct { - s *Service - project string - zone string - instance string - metadata *Metadata - opt_ map[string]interface{} -} - -// SetMetadata: Sets metadata for the specified instance to the data -// included in the request. -func (r *InstancesService) SetMetadata(project string, zone string, instance string, metadata *Metadata) *InstancesSetMetadataCall { - c := &InstancesSetMetadataCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.instance = instance - c.metadata = metadata - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *InstancesSetMetadataCall) Fields(s ...googleapi.Field) *InstancesSetMetadataCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *InstancesSetMetadataCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.metadata) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/setMetadata") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - "instance": c.instance, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Sets metadata for the specified instance to the data included in the request.", - // "httpMethod": "POST", - // "id": "compute.instances.setMetadata", - // "parameterOrder": [ - // "project", - // "zone", - // "instance" - // ], - // "parameters": { - // "instance": { - // "description": "Name of the instance scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/instances/{instance}/setMetadata", - // "request": { - // "$ref": "Metadata" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.instances.setScheduling": - -type InstancesSetSchedulingCall struct { - s *Service - project string - zone string - instance string - scheduling *Scheduling - opt_ map[string]interface{} -} - -// SetScheduling: Sets an instance's scheduling options. -func (r *InstancesService) SetScheduling(project string, zone string, instance string, scheduling *Scheduling) *InstancesSetSchedulingCall { - c := &InstancesSetSchedulingCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.instance = instance - c.scheduling = scheduling - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *InstancesSetSchedulingCall) Fields(s ...googleapi.Field) *InstancesSetSchedulingCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *InstancesSetSchedulingCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.scheduling) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/setScheduling") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - "instance": c.instance, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Sets an instance's scheduling options.", - // "httpMethod": "POST", - // "id": "compute.instances.setScheduling", - // "parameterOrder": [ - // "project", - // "zone", - // "instance" - // ], - // "parameters": { - // "instance": { - // "description": "Instance name.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Project name.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/instances/{instance}/setScheduling", - // "request": { - // "$ref": "Scheduling" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.instances.setTags": - -type InstancesSetTagsCall struct { - s *Service - project string - zone string - instance string - tags *Tags - opt_ map[string]interface{} -} - -// SetTags: Sets tags for the specified instance to the data included in -// the request. -func (r *InstancesService) SetTags(project string, zone string, instance string, tags *Tags) *InstancesSetTagsCall { - c := &InstancesSetTagsCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.instance = instance - c.tags = tags - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *InstancesSetTagsCall) Fields(s ...googleapi.Field) *InstancesSetTagsCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *InstancesSetTagsCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.tags) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/instances/{instance}/setTags") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - "instance": c.instance, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Sets tags for the specified instance to the data included in the request.", - // "httpMethod": "POST", - // "id": "compute.instances.setTags", - // "parameterOrder": [ - // "project", - // "zone", - // "instance" - // ], - // "parameters": { - // "instance": { - // "description": "Name of the instance scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/instances/{instance}/setTags", - // "request": { - // "$ref": "Tags" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.licenses.get": - -type LicensesGetCall struct { - s *Service - project string - license string - opt_ map[string]interface{} -} - -// Get: Returns the specified license resource. -func (r *LicensesService) Get(project string, license string) *LicensesGetCall { - c := &LicensesGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.license = license - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *LicensesGetCall) Fields(s ...googleapi.Field) *LicensesGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *LicensesGetCall) Do() (*License, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/licenses/{license}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "license": c.license, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *License - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified license resource.", - // "httpMethod": "GET", - // "id": "compute.licenses.get", - // "parameterOrder": [ - // "project", - // "license" - // ], - // "parameters": { - // "license": { - // "description": "Name of the license resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/licenses/{license}", - // "response": { - // "$ref": "License" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.machineTypes.aggregatedList": - -type MachineTypesAggregatedListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// AggregatedList: Retrieves the list of machine type resources grouped -// by scope. -func (r *MachineTypesService) AggregatedList(project string) *MachineTypesAggregatedListCall { - c := &MachineTypesAggregatedListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *MachineTypesAggregatedListCall) Filter(filter string) *MachineTypesAggregatedListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *MachineTypesAggregatedListCall) MaxResults(maxResults int64) *MachineTypesAggregatedListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *MachineTypesAggregatedListCall) PageToken(pageToken string) *MachineTypesAggregatedListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *MachineTypesAggregatedListCall) Fields(s ...googleapi.Field) *MachineTypesAggregatedListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *MachineTypesAggregatedListCall) Do() (*MachineTypeAggregatedList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/machineTypes") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *MachineTypeAggregatedList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of machine type resources grouped by scope.", - // "httpMethod": "GET", - // "id": "compute.machineTypes.aggregatedList", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/aggregated/machineTypes", - // "response": { - // "$ref": "MachineTypeAggregatedList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.machineTypes.get": - -type MachineTypesGetCall struct { - s *Service - project string - zone string - machineType string - opt_ map[string]interface{} -} - -// Get: Returns the specified machine type resource. -func (r *MachineTypesService) Get(project string, zone string, machineType string) *MachineTypesGetCall { - c := &MachineTypesGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.machineType = machineType - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *MachineTypesGetCall) Fields(s ...googleapi.Field) *MachineTypesGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *MachineTypesGetCall) Do() (*MachineType, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/machineTypes/{machineType}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - "machineType": c.machineType, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *MachineType - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified machine type resource.", - // "httpMethod": "GET", - // "id": "compute.machineTypes.get", - // "parameterOrder": [ - // "project", - // "zone", - // "machineType" - // ], - // "parameters": { - // "machineType": { - // "description": "Name of the machine type resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/machineTypes/{machineType}", - // "response": { - // "$ref": "MachineType" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.machineTypes.list": - -type MachineTypesListCall struct { - s *Service - project string - zone string - opt_ map[string]interface{} -} - -// List: Retrieves the list of machine type resources available to the -// specified project. -func (r *MachineTypesService) List(project string, zone string) *MachineTypesListCall { - c := &MachineTypesListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *MachineTypesListCall) Filter(filter string) *MachineTypesListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *MachineTypesListCall) MaxResults(maxResults int64) *MachineTypesListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *MachineTypesListCall) PageToken(pageToken string) *MachineTypesListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *MachineTypesListCall) Fields(s ...googleapi.Field) *MachineTypesListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *MachineTypesListCall) Do() (*MachineTypeList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/machineTypes") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *MachineTypeList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of machine type resources available to the specified project.", - // "httpMethod": "GET", - // "id": "compute.machineTypes.list", - // "parameterOrder": [ - // "project", - // "zone" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/machineTypes", - // "response": { - // "$ref": "MachineTypeList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.networks.delete": - -type NetworksDeleteCall struct { - s *Service - project string - network string - opt_ map[string]interface{} -} - -// Delete: Deletes the specified network resource. -func (r *NetworksService) Delete(project string, network string) *NetworksDeleteCall { - c := &NetworksDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.network = network - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *NetworksDeleteCall) Fields(s ...googleapi.Field) *NetworksDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *NetworksDeleteCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/networks/{network}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("DELETE", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "network": c.network, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Deletes the specified network resource.", - // "httpMethod": "DELETE", - // "id": "compute.networks.delete", - // "parameterOrder": [ - // "project", - // "network" - // ], - // "parameters": { - // "network": { - // "description": "Name of the network resource to delete.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/networks/{network}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.networks.get": - -type NetworksGetCall struct { - s *Service - project string - network string - opt_ map[string]interface{} -} - -// Get: Returns the specified network resource. -func (r *NetworksService) Get(project string, network string) *NetworksGetCall { - c := &NetworksGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.network = network - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *NetworksGetCall) Fields(s ...googleapi.Field) *NetworksGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *NetworksGetCall) Do() (*Network, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/networks/{network}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "network": c.network, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Network - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified network resource.", - // "httpMethod": "GET", - // "id": "compute.networks.get", - // "parameterOrder": [ - // "project", - // "network" - // ], - // "parameters": { - // "network": { - // "description": "Name of the network resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/networks/{network}", - // "response": { - // "$ref": "Network" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.networks.insert": - -type NetworksInsertCall struct { - s *Service - project string - network *Network - opt_ map[string]interface{} -} - -// Insert: Creates a network resource in the specified project using the -// data included in the request. -func (r *NetworksService) Insert(project string, network *Network) *NetworksInsertCall { - c := &NetworksInsertCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.network = network - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *NetworksInsertCall) Fields(s ...googleapi.Field) *NetworksInsertCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *NetworksInsertCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.network) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/networks") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Creates a network resource in the specified project using the data included in the request.", - // "httpMethod": "POST", - // "id": "compute.networks.insert", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/networks", - // "request": { - // "$ref": "Network" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.networks.list": - -type NetworksListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// List: Retrieves the list of network resources available to the -// specified project. -func (r *NetworksService) List(project string) *NetworksListCall { - c := &NetworksListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *NetworksListCall) Filter(filter string) *NetworksListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *NetworksListCall) MaxResults(maxResults int64) *NetworksListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *NetworksListCall) PageToken(pageToken string) *NetworksListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *NetworksListCall) Fields(s ...googleapi.Field) *NetworksListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *NetworksListCall) Do() (*NetworkList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/networks") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *NetworkList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of network resources available to the specified project.", - // "httpMethod": "GET", - // "id": "compute.networks.list", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/networks", - // "response": { - // "$ref": "NetworkList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.projects.get": - -type ProjectsGetCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// Get: Returns the specified project resource. -func (r *ProjectsService) Get(project string) *ProjectsGetCall { - c := &ProjectsGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ProjectsGetCall) Fields(s ...googleapi.Field) *ProjectsGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ProjectsGetCall) Do() (*Project, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Project - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified project resource.", - // "httpMethod": "GET", - // "id": "compute.projects.get", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project resource to retrieve.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}", - // "response": { - // "$ref": "Project" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.projects.setCommonInstanceMetadata": - -type ProjectsSetCommonInstanceMetadataCall struct { - s *Service - project string - metadata *Metadata - opt_ map[string]interface{} -} - -// SetCommonInstanceMetadata: Sets metadata common to all instances -// within the specified project using the data included in the request. -func (r *ProjectsService) SetCommonInstanceMetadata(project string, metadata *Metadata) *ProjectsSetCommonInstanceMetadataCall { - c := &ProjectsSetCommonInstanceMetadataCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.metadata = metadata - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ProjectsSetCommonInstanceMetadataCall) Fields(s ...googleapi.Field) *ProjectsSetCommonInstanceMetadataCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ProjectsSetCommonInstanceMetadataCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.metadata) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/setCommonInstanceMetadata") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Sets metadata common to all instances within the specified project using the data included in the request.", - // "httpMethod": "POST", - // "id": "compute.projects.setCommonInstanceMetadata", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/setCommonInstanceMetadata", - // "request": { - // "$ref": "Metadata" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.projects.setUsageExportBucket": - -type ProjectsSetUsageExportBucketCall struct { - s *Service - project string - usageexportlocation *UsageExportLocation - opt_ map[string]interface{} -} - -// SetUsageExportBucket: Sets usage export location -func (r *ProjectsService) SetUsageExportBucket(project string, usageexportlocation *UsageExportLocation) *ProjectsSetUsageExportBucketCall { - c := &ProjectsSetUsageExportBucketCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.usageexportlocation = usageexportlocation - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ProjectsSetUsageExportBucketCall) Fields(s ...googleapi.Field) *ProjectsSetUsageExportBucketCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ProjectsSetUsageExportBucketCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.usageexportlocation) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/setUsageExportBucket") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Sets usage export location", - // "httpMethod": "POST", - // "id": "compute.projects.setUsageExportBucket", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/setUsageExportBucket", - // "request": { - // "$ref": "UsageExportLocation" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/devstorage.full_control", - // "https://www.googleapis.com/auth/devstorage.read_only", - // "https://www.googleapis.com/auth/devstorage.read_write" - // ] - // } - -} - -// method id "compute.regionOperations.delete": - -type RegionOperationsDeleteCall struct { - s *Service - project string - region string - operation string - opt_ map[string]interface{} -} - -// Delete: Deletes the specified region-specific operation resource. -func (r *RegionOperationsService) Delete(project string, region string, operation string) *RegionOperationsDeleteCall { - c := &RegionOperationsDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - c.operation = operation - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *RegionOperationsDeleteCall) Fields(s ...googleapi.Field) *RegionOperationsDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *RegionOperationsDeleteCall) Do() error { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/operations/{operation}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("DELETE", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - "operation": c.operation, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return err - } - return nil - // { - // "description": "Deletes the specified region-specific operation resource.", - // "httpMethod": "DELETE", - // "id": "compute.regionOperations.delete", - // "parameterOrder": [ - // "project", - // "region", - // "operation" - // ], - // "parameters": { - // "operation": { - // "description": "Name of the operation resource to delete.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the region scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}/operations/{operation}", - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.regionOperations.get": - -type RegionOperationsGetCall struct { - s *Service - project string - region string - operation string - opt_ map[string]interface{} -} - -// Get: Retrieves the specified region-specific operation resource. -func (r *RegionOperationsService) Get(project string, region string, operation string) *RegionOperationsGetCall { - c := &RegionOperationsGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - c.operation = operation - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *RegionOperationsGetCall) Fields(s ...googleapi.Field) *RegionOperationsGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *RegionOperationsGetCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/operations/{operation}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - "operation": c.operation, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the specified region-specific operation resource.", - // "httpMethod": "GET", - // "id": "compute.regionOperations.get", - // "parameterOrder": [ - // "project", - // "region", - // "operation" - // ], - // "parameters": { - // "operation": { - // "description": "Name of the operation resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}/operations/{operation}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.regionOperations.list": - -type RegionOperationsListCall struct { - s *Service - project string - region string - opt_ map[string]interface{} -} - -// List: Retrieves the list of operation resources contained within the -// specified region. -func (r *RegionOperationsService) List(project string, region string) *RegionOperationsListCall { - c := &RegionOperationsListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *RegionOperationsListCall) Filter(filter string) *RegionOperationsListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *RegionOperationsListCall) MaxResults(maxResults int64) *RegionOperationsListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *RegionOperationsListCall) PageToken(pageToken string) *RegionOperationsListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *RegionOperationsListCall) Fields(s ...googleapi.Field) *RegionOperationsListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *RegionOperationsListCall) Do() (*OperationList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/operations") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *OperationList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of operation resources contained within the specified region.", - // "httpMethod": "GET", - // "id": "compute.regionOperations.list", - // "parameterOrder": [ - // "project", - // "region" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the region scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}/operations", - // "response": { - // "$ref": "OperationList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.regions.get": - -type RegionsGetCall struct { - s *Service - project string - region string - opt_ map[string]interface{} -} - -// Get: Returns the specified region resource. -func (r *RegionsService) Get(project string, region string) *RegionsGetCall { - c := &RegionsGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *RegionsGetCall) Fields(s ...googleapi.Field) *RegionsGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *RegionsGetCall) Do() (*Region, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Region - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified region resource.", - // "httpMethod": "GET", - // "id": "compute.regions.get", - // "parameterOrder": [ - // "project", - // "region" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the region resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}", - // "response": { - // "$ref": "Region" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.regions.list": - -type RegionsListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// List: Retrieves the list of region resources available to the -// specified project. -func (r *RegionsService) List(project string) *RegionsListCall { - c := &RegionsListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *RegionsListCall) Filter(filter string) *RegionsListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *RegionsListCall) MaxResults(maxResults int64) *RegionsListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *RegionsListCall) PageToken(pageToken string) *RegionsListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *RegionsListCall) Fields(s ...googleapi.Field) *RegionsListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *RegionsListCall) Do() (*RegionList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *RegionList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of region resources available to the specified project.", - // "httpMethod": "GET", - // "id": "compute.regions.list", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions", - // "response": { - // "$ref": "RegionList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.routes.delete": - -type RoutesDeleteCall struct { - s *Service - project string - route string - opt_ map[string]interface{} -} - -// Delete: Deletes the specified route resource. -func (r *RoutesService) Delete(project string, route string) *RoutesDeleteCall { - c := &RoutesDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.route = route - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *RoutesDeleteCall) Fields(s ...googleapi.Field) *RoutesDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *RoutesDeleteCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/routes/{route}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("DELETE", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "route": c.route, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Deletes the specified route resource.", - // "httpMethod": "DELETE", - // "id": "compute.routes.delete", - // "parameterOrder": [ - // "project", - // "route" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "route": { - // "description": "Name of the route resource to delete.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/routes/{route}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.routes.get": - -type RoutesGetCall struct { - s *Service - project string - route string - opt_ map[string]interface{} -} - -// Get: Returns the specified route resource. -func (r *RoutesService) Get(project string, route string) *RoutesGetCall { - c := &RoutesGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.route = route - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *RoutesGetCall) Fields(s ...googleapi.Field) *RoutesGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *RoutesGetCall) Do() (*Route, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/routes/{route}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "route": c.route, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Route - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified route resource.", - // "httpMethod": "GET", - // "id": "compute.routes.get", - // "parameterOrder": [ - // "project", - // "route" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "route": { - // "description": "Name of the route resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/routes/{route}", - // "response": { - // "$ref": "Route" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.routes.insert": - -type RoutesInsertCall struct { - s *Service - project string - route *Route - opt_ map[string]interface{} -} - -// Insert: Creates a route resource in the specified project using the -// data included in the request. -func (r *RoutesService) Insert(project string, route *Route) *RoutesInsertCall { - c := &RoutesInsertCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.route = route - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *RoutesInsertCall) Fields(s ...googleapi.Field) *RoutesInsertCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *RoutesInsertCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.route) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/routes") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Creates a route resource in the specified project using the data included in the request.", - // "httpMethod": "POST", - // "id": "compute.routes.insert", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/routes", - // "request": { - // "$ref": "Route" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.routes.list": - -type RoutesListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// List: Retrieves the list of route resources available to the -// specified project. -func (r *RoutesService) List(project string) *RoutesListCall { - c := &RoutesListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *RoutesListCall) Filter(filter string) *RoutesListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *RoutesListCall) MaxResults(maxResults int64) *RoutesListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *RoutesListCall) PageToken(pageToken string) *RoutesListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *RoutesListCall) Fields(s ...googleapi.Field) *RoutesListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *RoutesListCall) Do() (*RouteList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/routes") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *RouteList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of route resources available to the specified project.", - // "httpMethod": "GET", - // "id": "compute.routes.list", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/routes", - // "response": { - // "$ref": "RouteList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.snapshots.delete": - -type SnapshotsDeleteCall struct { - s *Service - project string - snapshot string - opt_ map[string]interface{} -} - -// Delete: Deletes the specified persistent disk snapshot resource. -func (r *SnapshotsService) Delete(project string, snapshot string) *SnapshotsDeleteCall { - c := &SnapshotsDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.snapshot = snapshot - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *SnapshotsDeleteCall) Fields(s ...googleapi.Field) *SnapshotsDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *SnapshotsDeleteCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/snapshots/{snapshot}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("DELETE", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "snapshot": c.snapshot, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Deletes the specified persistent disk snapshot resource.", - // "httpMethod": "DELETE", - // "id": "compute.snapshots.delete", - // "parameterOrder": [ - // "project", - // "snapshot" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "snapshot": { - // "description": "Name of the persistent disk snapshot resource to delete.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/snapshots/{snapshot}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.snapshots.get": - -type SnapshotsGetCall struct { - s *Service - project string - snapshot string - opt_ map[string]interface{} -} - -// Get: Returns the specified persistent disk snapshot resource. -func (r *SnapshotsService) Get(project string, snapshot string) *SnapshotsGetCall { - c := &SnapshotsGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.snapshot = snapshot - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *SnapshotsGetCall) Fields(s ...googleapi.Field) *SnapshotsGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *SnapshotsGetCall) Do() (*Snapshot, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/snapshots/{snapshot}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "snapshot": c.snapshot, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Snapshot - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified persistent disk snapshot resource.", - // "httpMethod": "GET", - // "id": "compute.snapshots.get", - // "parameterOrder": [ - // "project", - // "snapshot" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "snapshot": { - // "description": "Name of the persistent disk snapshot resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/snapshots/{snapshot}", - // "response": { - // "$ref": "Snapshot" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.snapshots.list": - -type SnapshotsListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// List: Retrieves the list of persistent disk snapshot resources -// contained within the specified project. -func (r *SnapshotsService) List(project string) *SnapshotsListCall { - c := &SnapshotsListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *SnapshotsListCall) Filter(filter string) *SnapshotsListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *SnapshotsListCall) MaxResults(maxResults int64) *SnapshotsListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *SnapshotsListCall) PageToken(pageToken string) *SnapshotsListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *SnapshotsListCall) Fields(s ...googleapi.Field) *SnapshotsListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *SnapshotsListCall) Do() (*SnapshotList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/snapshots") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *SnapshotList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of persistent disk snapshot resources contained within the specified project.", - // "httpMethod": "GET", - // "id": "compute.snapshots.list", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/snapshots", - // "response": { - // "$ref": "SnapshotList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.targetHttpProxies.delete": - -type TargetHttpProxiesDeleteCall struct { - s *Service - project string - targetHttpProxy string - opt_ map[string]interface{} -} - -// Delete: Deletes the specified TargetHttpProxy resource. -func (r *TargetHttpProxiesService) Delete(project string, targetHttpProxy string) *TargetHttpProxiesDeleteCall { - c := &TargetHttpProxiesDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.targetHttpProxy = targetHttpProxy - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *TargetHttpProxiesDeleteCall) Fields(s ...googleapi.Field) *TargetHttpProxiesDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *TargetHttpProxiesDeleteCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetHttpProxies/{targetHttpProxy}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("DELETE", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "targetHttpProxy": c.targetHttpProxy, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Deletes the specified TargetHttpProxy resource.", - // "httpMethod": "DELETE", - // "id": "compute.targetHttpProxies.delete", - // "parameterOrder": [ - // "project", - // "targetHttpProxy" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "targetHttpProxy": { - // "description": "Name of the TargetHttpProxy resource to delete.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/targetHttpProxies/{targetHttpProxy}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.targetHttpProxies.get": - -type TargetHttpProxiesGetCall struct { - s *Service - project string - targetHttpProxy string - opt_ map[string]interface{} -} - -// Get: Returns the specified TargetHttpProxy resource. -func (r *TargetHttpProxiesService) Get(project string, targetHttpProxy string) *TargetHttpProxiesGetCall { - c := &TargetHttpProxiesGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.targetHttpProxy = targetHttpProxy - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *TargetHttpProxiesGetCall) Fields(s ...googleapi.Field) *TargetHttpProxiesGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *TargetHttpProxiesGetCall) Do() (*TargetHttpProxy, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetHttpProxies/{targetHttpProxy}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "targetHttpProxy": c.targetHttpProxy, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *TargetHttpProxy - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified TargetHttpProxy resource.", - // "httpMethod": "GET", - // "id": "compute.targetHttpProxies.get", - // "parameterOrder": [ - // "project", - // "targetHttpProxy" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "targetHttpProxy": { - // "description": "Name of the TargetHttpProxy resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/targetHttpProxies/{targetHttpProxy}", - // "response": { - // "$ref": "TargetHttpProxy" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.targetHttpProxies.insert": - -type TargetHttpProxiesInsertCall struct { - s *Service - project string - targethttpproxy *TargetHttpProxy - opt_ map[string]interface{} -} - -// Insert: Creates a TargetHttpProxy resource in the specified project -// using the data included in the request. -func (r *TargetHttpProxiesService) Insert(project string, targethttpproxy *TargetHttpProxy) *TargetHttpProxiesInsertCall { - c := &TargetHttpProxiesInsertCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.targethttpproxy = targethttpproxy - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *TargetHttpProxiesInsertCall) Fields(s ...googleapi.Field) *TargetHttpProxiesInsertCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *TargetHttpProxiesInsertCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.targethttpproxy) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetHttpProxies") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Creates a TargetHttpProxy resource in the specified project using the data included in the request.", - // "httpMethod": "POST", - // "id": "compute.targetHttpProxies.insert", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/targetHttpProxies", - // "request": { - // "$ref": "TargetHttpProxy" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.targetHttpProxies.list": - -type TargetHttpProxiesListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// List: Retrieves the list of TargetHttpProxy resources available to -// the specified project. -func (r *TargetHttpProxiesService) List(project string) *TargetHttpProxiesListCall { - c := &TargetHttpProxiesListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *TargetHttpProxiesListCall) Filter(filter string) *TargetHttpProxiesListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *TargetHttpProxiesListCall) MaxResults(maxResults int64) *TargetHttpProxiesListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *TargetHttpProxiesListCall) PageToken(pageToken string) *TargetHttpProxiesListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *TargetHttpProxiesListCall) Fields(s ...googleapi.Field) *TargetHttpProxiesListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *TargetHttpProxiesListCall) Do() (*TargetHttpProxyList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/targetHttpProxies") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *TargetHttpProxyList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of TargetHttpProxy resources available to the specified project.", - // "httpMethod": "GET", - // "id": "compute.targetHttpProxies.list", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/targetHttpProxies", - // "response": { - // "$ref": "TargetHttpProxyList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.targetHttpProxies.setUrlMap": - -type TargetHttpProxiesSetUrlMapCall struct { - s *Service - project string - targetHttpProxy string - urlmapreference *UrlMapReference - opt_ map[string]interface{} -} - -// SetUrlMap: Changes the URL map for TargetHttpProxy. -func (r *TargetHttpProxiesService) SetUrlMap(project string, targetHttpProxy string, urlmapreference *UrlMapReference) *TargetHttpProxiesSetUrlMapCall { - c := &TargetHttpProxiesSetUrlMapCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.targetHttpProxy = targetHttpProxy - c.urlmapreference = urlmapreference - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *TargetHttpProxiesSetUrlMapCall) Fields(s ...googleapi.Field) *TargetHttpProxiesSetUrlMapCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *TargetHttpProxiesSetUrlMapCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.urlmapreference) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/targetHttpProxies/{targetHttpProxy}/setUrlMap") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "targetHttpProxy": c.targetHttpProxy, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Changes the URL map for TargetHttpProxy.", - // "httpMethod": "POST", - // "id": "compute.targetHttpProxies.setUrlMap", - // "parameterOrder": [ - // "project", - // "targetHttpProxy" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "targetHttpProxy": { - // "description": "Name of the TargetHttpProxy resource whose URL map is to be set.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/targetHttpProxies/{targetHttpProxy}/setUrlMap", - // "request": { - // "$ref": "UrlMapReference" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.targetInstances.aggregatedList": - -type TargetInstancesAggregatedListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// AggregatedList: Retrieves the list of target instances grouped by -// scope. -func (r *TargetInstancesService) AggregatedList(project string) *TargetInstancesAggregatedListCall { - c := &TargetInstancesAggregatedListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *TargetInstancesAggregatedListCall) Filter(filter string) *TargetInstancesAggregatedListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *TargetInstancesAggregatedListCall) MaxResults(maxResults int64) *TargetInstancesAggregatedListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *TargetInstancesAggregatedListCall) PageToken(pageToken string) *TargetInstancesAggregatedListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *TargetInstancesAggregatedListCall) Fields(s ...googleapi.Field) *TargetInstancesAggregatedListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *TargetInstancesAggregatedListCall) Do() (*TargetInstanceAggregatedList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/targetInstances") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *TargetInstanceAggregatedList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of target instances grouped by scope.", - // "httpMethod": "GET", - // "id": "compute.targetInstances.aggregatedList", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/aggregated/targetInstances", - // "response": { - // "$ref": "TargetInstanceAggregatedList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.targetInstances.delete": - -type TargetInstancesDeleteCall struct { - s *Service - project string - zone string - targetInstance string - opt_ map[string]interface{} -} - -// Delete: Deletes the specified TargetInstance resource. -func (r *TargetInstancesService) Delete(project string, zone string, targetInstance string) *TargetInstancesDeleteCall { - c := &TargetInstancesDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.targetInstance = targetInstance - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *TargetInstancesDeleteCall) Fields(s ...googleapi.Field) *TargetInstancesDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *TargetInstancesDeleteCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/targetInstances/{targetInstance}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("DELETE", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - "targetInstance": c.targetInstance, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Deletes the specified TargetInstance resource.", - // "httpMethod": "DELETE", - // "id": "compute.targetInstances.delete", - // "parameterOrder": [ - // "project", - // "zone", - // "targetInstance" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "targetInstance": { - // "description": "Name of the TargetInstance resource to delete.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/targetInstances/{targetInstance}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.targetInstances.get": - -type TargetInstancesGetCall struct { - s *Service - project string - zone string - targetInstance string - opt_ map[string]interface{} -} - -// Get: Returns the specified TargetInstance resource. -func (r *TargetInstancesService) Get(project string, zone string, targetInstance string) *TargetInstancesGetCall { - c := &TargetInstancesGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.targetInstance = targetInstance - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *TargetInstancesGetCall) Fields(s ...googleapi.Field) *TargetInstancesGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *TargetInstancesGetCall) Do() (*TargetInstance, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/targetInstances/{targetInstance}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - "targetInstance": c.targetInstance, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *TargetInstance - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified TargetInstance resource.", - // "httpMethod": "GET", - // "id": "compute.targetInstances.get", - // "parameterOrder": [ - // "project", - // "zone", - // "targetInstance" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "targetInstance": { - // "description": "Name of the TargetInstance resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/targetInstances/{targetInstance}", - // "response": { - // "$ref": "TargetInstance" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.targetInstances.insert": - -type TargetInstancesInsertCall struct { - s *Service - project string - zone string - targetinstance *TargetInstance - opt_ map[string]interface{} -} - -// Insert: Creates a TargetInstance resource in the specified project -// and zone using the data included in the request. -func (r *TargetInstancesService) Insert(project string, zone string, targetinstance *TargetInstance) *TargetInstancesInsertCall { - c := &TargetInstancesInsertCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.targetinstance = targetinstance - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *TargetInstancesInsertCall) Fields(s ...googleapi.Field) *TargetInstancesInsertCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *TargetInstancesInsertCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetinstance) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/targetInstances") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Creates a TargetInstance resource in the specified project and zone using the data included in the request.", - // "httpMethod": "POST", - // "id": "compute.targetInstances.insert", - // "parameterOrder": [ - // "project", - // "zone" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/targetInstances", - // "request": { - // "$ref": "TargetInstance" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.targetInstances.list": - -type TargetInstancesListCall struct { - s *Service - project string - zone string - opt_ map[string]interface{} -} - -// List: Retrieves the list of TargetInstance resources available to the -// specified project and zone. -func (r *TargetInstancesService) List(project string, zone string) *TargetInstancesListCall { - c := &TargetInstancesListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *TargetInstancesListCall) Filter(filter string) *TargetInstancesListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *TargetInstancesListCall) MaxResults(maxResults int64) *TargetInstancesListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *TargetInstancesListCall) PageToken(pageToken string) *TargetInstancesListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *TargetInstancesListCall) Fields(s ...googleapi.Field) *TargetInstancesListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *TargetInstancesListCall) Do() (*TargetInstanceList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/targetInstances") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *TargetInstanceList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of TargetInstance resources available to the specified project and zone.", - // "httpMethod": "GET", - // "id": "compute.targetInstances.list", - // "parameterOrder": [ - // "project", - // "zone" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/targetInstances", - // "response": { - // "$ref": "TargetInstanceList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.targetPools.addHealthCheck": - -type TargetPoolsAddHealthCheckCall struct { - s *Service - project string - region string - targetPool string - targetpoolsaddhealthcheckrequest *TargetPoolsAddHealthCheckRequest - opt_ map[string]interface{} -} - -// AddHealthCheck: Adds health check URL to targetPool. -func (r *TargetPoolsService) AddHealthCheck(project string, region string, targetPool string, targetpoolsaddhealthcheckrequest *TargetPoolsAddHealthCheckRequest) *TargetPoolsAddHealthCheckCall { - c := &TargetPoolsAddHealthCheckCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - c.targetPool = targetPool - c.targetpoolsaddhealthcheckrequest = targetpoolsaddhealthcheckrequest - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *TargetPoolsAddHealthCheckCall) Fields(s ...googleapi.Field) *TargetPoolsAddHealthCheckCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *TargetPoolsAddHealthCheckCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetpoolsaddhealthcheckrequest) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetPools/{targetPool}/addHealthCheck") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - "targetPool": c.targetPool, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Adds health check URL to targetPool.", - // "httpMethod": "POST", - // "id": "compute.targetPools.addHealthCheck", - // "parameterOrder": [ - // "project", - // "region", - // "targetPool" - // ], - // "parameters": { - // "project": { - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the region scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "targetPool": { - // "description": "Name of the TargetPool resource to which health_check_url is to be added.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}/targetPools/{targetPool}/addHealthCheck", - // "request": { - // "$ref": "TargetPoolsAddHealthCheckRequest" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.targetPools.addInstance": - -type TargetPoolsAddInstanceCall struct { - s *Service - project string - region string - targetPool string - targetpoolsaddinstancerequest *TargetPoolsAddInstanceRequest - opt_ map[string]interface{} -} - -// AddInstance: Adds instance url to targetPool. -func (r *TargetPoolsService) AddInstance(project string, region string, targetPool string, targetpoolsaddinstancerequest *TargetPoolsAddInstanceRequest) *TargetPoolsAddInstanceCall { - c := &TargetPoolsAddInstanceCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - c.targetPool = targetPool - c.targetpoolsaddinstancerequest = targetpoolsaddinstancerequest - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *TargetPoolsAddInstanceCall) Fields(s ...googleapi.Field) *TargetPoolsAddInstanceCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *TargetPoolsAddInstanceCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetpoolsaddinstancerequest) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetPools/{targetPool}/addInstance") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - "targetPool": c.targetPool, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Adds instance url to targetPool.", - // "httpMethod": "POST", - // "id": "compute.targetPools.addInstance", - // "parameterOrder": [ - // "project", - // "region", - // "targetPool" - // ], - // "parameters": { - // "project": { - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the region scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "targetPool": { - // "description": "Name of the TargetPool resource to which instance_url is to be added.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}/targetPools/{targetPool}/addInstance", - // "request": { - // "$ref": "TargetPoolsAddInstanceRequest" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.targetPools.aggregatedList": - -type TargetPoolsAggregatedListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// AggregatedList: Retrieves the list of target pools grouped by scope. -func (r *TargetPoolsService) AggregatedList(project string) *TargetPoolsAggregatedListCall { - c := &TargetPoolsAggregatedListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *TargetPoolsAggregatedListCall) Filter(filter string) *TargetPoolsAggregatedListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *TargetPoolsAggregatedListCall) MaxResults(maxResults int64) *TargetPoolsAggregatedListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *TargetPoolsAggregatedListCall) PageToken(pageToken string) *TargetPoolsAggregatedListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *TargetPoolsAggregatedListCall) Fields(s ...googleapi.Field) *TargetPoolsAggregatedListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *TargetPoolsAggregatedListCall) Do() (*TargetPoolAggregatedList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/aggregated/targetPools") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *TargetPoolAggregatedList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of target pools grouped by scope.", - // "httpMethod": "GET", - // "id": "compute.targetPools.aggregatedList", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/aggregated/targetPools", - // "response": { - // "$ref": "TargetPoolAggregatedList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.targetPools.delete": - -type TargetPoolsDeleteCall struct { - s *Service - project string - region string - targetPool string - opt_ map[string]interface{} -} - -// Delete: Deletes the specified TargetPool resource. -func (r *TargetPoolsService) Delete(project string, region string, targetPool string) *TargetPoolsDeleteCall { - c := &TargetPoolsDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - c.targetPool = targetPool - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *TargetPoolsDeleteCall) Fields(s ...googleapi.Field) *TargetPoolsDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *TargetPoolsDeleteCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetPools/{targetPool}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("DELETE", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - "targetPool": c.targetPool, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Deletes the specified TargetPool resource.", - // "httpMethod": "DELETE", - // "id": "compute.targetPools.delete", - // "parameterOrder": [ - // "project", - // "region", - // "targetPool" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the region scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "targetPool": { - // "description": "Name of the TargetPool resource to delete.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}/targetPools/{targetPool}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.targetPools.get": - -type TargetPoolsGetCall struct { - s *Service - project string - region string - targetPool string - opt_ map[string]interface{} -} - -// Get: Returns the specified TargetPool resource. -func (r *TargetPoolsService) Get(project string, region string, targetPool string) *TargetPoolsGetCall { - c := &TargetPoolsGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - c.targetPool = targetPool - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *TargetPoolsGetCall) Fields(s ...googleapi.Field) *TargetPoolsGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *TargetPoolsGetCall) Do() (*TargetPool, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetPools/{targetPool}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - "targetPool": c.targetPool, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *TargetPool - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified TargetPool resource.", - // "httpMethod": "GET", - // "id": "compute.targetPools.get", - // "parameterOrder": [ - // "project", - // "region", - // "targetPool" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the region scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "targetPool": { - // "description": "Name of the TargetPool resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}/targetPools/{targetPool}", - // "response": { - // "$ref": "TargetPool" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.targetPools.getHealth": - -type TargetPoolsGetHealthCall struct { - s *Service - project string - region string - targetPool string - instancereference *InstanceReference - opt_ map[string]interface{} -} - -// GetHealth: Gets the most recent health check results for each IP for -// the given instance that is referenced by given TargetPool. -func (r *TargetPoolsService) GetHealth(project string, region string, targetPool string, instancereference *InstanceReference) *TargetPoolsGetHealthCall { - c := &TargetPoolsGetHealthCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - c.targetPool = targetPool - c.instancereference = instancereference - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *TargetPoolsGetHealthCall) Fields(s ...googleapi.Field) *TargetPoolsGetHealthCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *TargetPoolsGetHealthCall) Do() (*TargetPoolInstanceHealth, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.instancereference) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetPools/{targetPool}/getHealth") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - "targetPool": c.targetPool, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *TargetPoolInstanceHealth - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Gets the most recent health check results for each IP for the given instance that is referenced by given TargetPool.", - // "httpMethod": "POST", - // "id": "compute.targetPools.getHealth", - // "parameterOrder": [ - // "project", - // "region", - // "targetPool" - // ], - // "parameters": { - // "project": { - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the region scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "targetPool": { - // "description": "Name of the TargetPool resource to which the queried instance belongs.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}/targetPools/{targetPool}/getHealth", - // "request": { - // "$ref": "InstanceReference" - // }, - // "response": { - // "$ref": "TargetPoolInstanceHealth" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.targetPools.insert": - -type TargetPoolsInsertCall struct { - s *Service - project string - region string - targetpool *TargetPool - opt_ map[string]interface{} -} - -// Insert: Creates a TargetPool resource in the specified project and -// region using the data included in the request. -func (r *TargetPoolsService) Insert(project string, region string, targetpool *TargetPool) *TargetPoolsInsertCall { - c := &TargetPoolsInsertCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - c.targetpool = targetpool - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *TargetPoolsInsertCall) Fields(s ...googleapi.Field) *TargetPoolsInsertCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *TargetPoolsInsertCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetpool) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetPools") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Creates a TargetPool resource in the specified project and region using the data included in the request.", - // "httpMethod": "POST", - // "id": "compute.targetPools.insert", - // "parameterOrder": [ - // "project", - // "region" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the region scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}/targetPools", - // "request": { - // "$ref": "TargetPool" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.targetPools.list": - -type TargetPoolsListCall struct { - s *Service - project string - region string - opt_ map[string]interface{} -} - -// List: Retrieves the list of TargetPool resources available to the -// specified project and region. -func (r *TargetPoolsService) List(project string, region string) *TargetPoolsListCall { - c := &TargetPoolsListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *TargetPoolsListCall) Filter(filter string) *TargetPoolsListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *TargetPoolsListCall) MaxResults(maxResults int64) *TargetPoolsListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *TargetPoolsListCall) PageToken(pageToken string) *TargetPoolsListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *TargetPoolsListCall) Fields(s ...googleapi.Field) *TargetPoolsListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *TargetPoolsListCall) Do() (*TargetPoolList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetPools") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *TargetPoolList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of TargetPool resources available to the specified project and region.", - // "httpMethod": "GET", - // "id": "compute.targetPools.list", - // "parameterOrder": [ - // "project", - // "region" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the region scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}/targetPools", - // "response": { - // "$ref": "TargetPoolList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.targetPools.removeHealthCheck": - -type TargetPoolsRemoveHealthCheckCall struct { - s *Service - project string - region string - targetPool string - targetpoolsremovehealthcheckrequest *TargetPoolsRemoveHealthCheckRequest - opt_ map[string]interface{} -} - -// RemoveHealthCheck: Removes health check URL from targetPool. -func (r *TargetPoolsService) RemoveHealthCheck(project string, region string, targetPool string, targetpoolsremovehealthcheckrequest *TargetPoolsRemoveHealthCheckRequest) *TargetPoolsRemoveHealthCheckCall { - c := &TargetPoolsRemoveHealthCheckCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - c.targetPool = targetPool - c.targetpoolsremovehealthcheckrequest = targetpoolsremovehealthcheckrequest - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *TargetPoolsRemoveHealthCheckCall) Fields(s ...googleapi.Field) *TargetPoolsRemoveHealthCheckCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *TargetPoolsRemoveHealthCheckCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetpoolsremovehealthcheckrequest) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetPools/{targetPool}/removeHealthCheck") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - "targetPool": c.targetPool, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Removes health check URL from targetPool.", - // "httpMethod": "POST", - // "id": "compute.targetPools.removeHealthCheck", - // "parameterOrder": [ - // "project", - // "region", - // "targetPool" - // ], - // "parameters": { - // "project": { - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the region scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "targetPool": { - // "description": "Name of the TargetPool resource to which health_check_url is to be removed.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}/targetPools/{targetPool}/removeHealthCheck", - // "request": { - // "$ref": "TargetPoolsRemoveHealthCheckRequest" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.targetPools.removeInstance": - -type TargetPoolsRemoveInstanceCall struct { - s *Service - project string - region string - targetPool string - targetpoolsremoveinstancerequest *TargetPoolsRemoveInstanceRequest - opt_ map[string]interface{} -} - -// RemoveInstance: Removes instance URL from targetPool. -func (r *TargetPoolsService) RemoveInstance(project string, region string, targetPool string, targetpoolsremoveinstancerequest *TargetPoolsRemoveInstanceRequest) *TargetPoolsRemoveInstanceCall { - c := &TargetPoolsRemoveInstanceCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - c.targetPool = targetPool - c.targetpoolsremoveinstancerequest = targetpoolsremoveinstancerequest - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *TargetPoolsRemoveInstanceCall) Fields(s ...googleapi.Field) *TargetPoolsRemoveInstanceCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *TargetPoolsRemoveInstanceCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetpoolsremoveinstancerequest) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetPools/{targetPool}/removeInstance") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - "targetPool": c.targetPool, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Removes instance URL from targetPool.", - // "httpMethod": "POST", - // "id": "compute.targetPools.removeInstance", - // "parameterOrder": [ - // "project", - // "region", - // "targetPool" - // ], - // "parameters": { - // "project": { - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the region scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "targetPool": { - // "description": "Name of the TargetPool resource to which instance_url is to be removed.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}/targetPools/{targetPool}/removeInstance", - // "request": { - // "$ref": "TargetPoolsRemoveInstanceRequest" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.targetPools.setBackup": - -type TargetPoolsSetBackupCall struct { - s *Service - project string - region string - targetPool string - targetreference *TargetReference - opt_ map[string]interface{} -} - -// SetBackup: Changes backup pool configurations. -func (r *TargetPoolsService) SetBackup(project string, region string, targetPool string, targetreference *TargetReference) *TargetPoolsSetBackupCall { - c := &TargetPoolsSetBackupCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.region = region - c.targetPool = targetPool - c.targetreference = targetreference - return c -} - -// FailoverRatio sets the optional parameter "failoverRatio": New -// failoverRatio value for the containing target pool. -func (c *TargetPoolsSetBackupCall) FailoverRatio(failoverRatio float64) *TargetPoolsSetBackupCall { - c.opt_["failoverRatio"] = failoverRatio - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *TargetPoolsSetBackupCall) Fields(s ...googleapi.Field) *TargetPoolsSetBackupCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *TargetPoolsSetBackupCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetreference) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["failoverRatio"]; ok { - params.Set("failoverRatio", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/regions/{region}/targetPools/{targetPool}/setBackup") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "region": c.region, - "targetPool": c.targetPool, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Changes backup pool configurations.", - // "httpMethod": "POST", - // "id": "compute.targetPools.setBackup", - // "parameterOrder": [ - // "project", - // "region", - // "targetPool" - // ], - // "parameters": { - // "failoverRatio": { - // "description": "New failoverRatio value for the containing target pool.", - // "format": "float", - // "location": "query", - // "type": "number" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "region": { - // "description": "Name of the region scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "targetPool": { - // "description": "Name of the TargetPool resource for which the backup is to be set.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/regions/{region}/targetPools/{targetPool}/setBackup", - // "request": { - // "$ref": "TargetReference" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.urlMaps.delete": - -type UrlMapsDeleteCall struct { - s *Service - project string - urlMap string - opt_ map[string]interface{} -} - -// Delete: Deletes the specified UrlMap resource. -func (r *UrlMapsService) Delete(project string, urlMap string) *UrlMapsDeleteCall { - c := &UrlMapsDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.urlMap = urlMap - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *UrlMapsDeleteCall) Fields(s ...googleapi.Field) *UrlMapsDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *UrlMapsDeleteCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/urlMaps/{urlMap}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("DELETE", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "urlMap": c.urlMap, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Deletes the specified UrlMap resource.", - // "httpMethod": "DELETE", - // "id": "compute.urlMaps.delete", - // "parameterOrder": [ - // "project", - // "urlMap" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "urlMap": { - // "description": "Name of the UrlMap resource to delete.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/urlMaps/{urlMap}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.urlMaps.get": - -type UrlMapsGetCall struct { - s *Service - project string - urlMap string - opt_ map[string]interface{} -} - -// Get: Returns the specified UrlMap resource. -func (r *UrlMapsService) Get(project string, urlMap string) *UrlMapsGetCall { - c := &UrlMapsGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.urlMap = urlMap - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *UrlMapsGetCall) Fields(s ...googleapi.Field) *UrlMapsGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *UrlMapsGetCall) Do() (*UrlMap, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/urlMaps/{urlMap}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "urlMap": c.urlMap, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *UrlMap - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified UrlMap resource.", - // "httpMethod": "GET", - // "id": "compute.urlMaps.get", - // "parameterOrder": [ - // "project", - // "urlMap" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "urlMap": { - // "description": "Name of the UrlMap resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/urlMaps/{urlMap}", - // "response": { - // "$ref": "UrlMap" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.urlMaps.insert": - -type UrlMapsInsertCall struct { - s *Service - project string - urlmap *UrlMap - opt_ map[string]interface{} -} - -// Insert: Creates a UrlMap resource in the specified project using the -// data included in the request. -func (r *UrlMapsService) Insert(project string, urlmap *UrlMap) *UrlMapsInsertCall { - c := &UrlMapsInsertCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.urlmap = urlmap - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *UrlMapsInsertCall) Fields(s ...googleapi.Field) *UrlMapsInsertCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *UrlMapsInsertCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.urlmap) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/urlMaps") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Creates a UrlMap resource in the specified project using the data included in the request.", - // "httpMethod": "POST", - // "id": "compute.urlMaps.insert", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/urlMaps", - // "request": { - // "$ref": "UrlMap" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.urlMaps.list": - -type UrlMapsListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// List: Retrieves the list of UrlMap resources available to the -// specified project. -func (r *UrlMapsService) List(project string) *UrlMapsListCall { - c := &UrlMapsListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *UrlMapsListCall) Filter(filter string) *UrlMapsListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *UrlMapsListCall) MaxResults(maxResults int64) *UrlMapsListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *UrlMapsListCall) PageToken(pageToken string) *UrlMapsListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *UrlMapsListCall) Fields(s ...googleapi.Field) *UrlMapsListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *UrlMapsListCall) Do() (*UrlMapList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/urlMaps") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *UrlMapList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of UrlMap resources available to the specified project.", - // "httpMethod": "GET", - // "id": "compute.urlMaps.list", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/urlMaps", - // "response": { - // "$ref": "UrlMapList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.urlMaps.patch": - -type UrlMapsPatchCall struct { - s *Service - project string - urlMap string - urlmap *UrlMap - opt_ map[string]interface{} -} - -// Patch: Update the entire content of the UrlMap resource. This method -// supports patch semantics. -func (r *UrlMapsService) Patch(project string, urlMap string, urlmap *UrlMap) *UrlMapsPatchCall { - c := &UrlMapsPatchCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.urlMap = urlMap - c.urlmap = urlmap - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *UrlMapsPatchCall) Fields(s ...googleapi.Field) *UrlMapsPatchCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *UrlMapsPatchCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.urlmap) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/urlMaps/{urlMap}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("PATCH", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "urlMap": c.urlMap, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Update the entire content of the UrlMap resource. This method supports patch semantics.", - // "httpMethod": "PATCH", - // "id": "compute.urlMaps.patch", - // "parameterOrder": [ - // "project", - // "urlMap" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "urlMap": { - // "description": "Name of the UrlMap resource to update.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/urlMaps/{urlMap}", - // "request": { - // "$ref": "UrlMap" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.urlMaps.update": - -type UrlMapsUpdateCall struct { - s *Service - project string - urlMap string - urlmap *UrlMap - opt_ map[string]interface{} -} - -// Update: Update the entire content of the UrlMap resource. -func (r *UrlMapsService) Update(project string, urlMap string, urlmap *UrlMap) *UrlMapsUpdateCall { - c := &UrlMapsUpdateCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.urlMap = urlMap - c.urlmap = urlmap - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *UrlMapsUpdateCall) Fields(s ...googleapi.Field) *UrlMapsUpdateCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *UrlMapsUpdateCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.urlmap) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/urlMaps/{urlMap}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("PUT", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "urlMap": c.urlMap, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Update the entire content of the UrlMap resource.", - // "httpMethod": "PUT", - // "id": "compute.urlMaps.update", - // "parameterOrder": [ - // "project", - // "urlMap" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "urlMap": { - // "description": "Name of the UrlMap resource to update.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/urlMaps/{urlMap}", - // "request": { - // "$ref": "UrlMap" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.urlMaps.validate": - -type UrlMapsValidateCall struct { - s *Service - project string - urlMap string - urlmapsvalidaterequest *UrlMapsValidateRequest - opt_ map[string]interface{} -} - -// Validate: Run static validation for the UrlMap. In particular, the -// tests of the provided UrlMap will be run. Calling this method does -// NOT create the UrlMap. -func (r *UrlMapsService) Validate(project string, urlMap string, urlmapsvalidaterequest *UrlMapsValidateRequest) *UrlMapsValidateCall { - c := &UrlMapsValidateCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.urlMap = urlMap - c.urlmapsvalidaterequest = urlmapsvalidaterequest - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *UrlMapsValidateCall) Fields(s ...googleapi.Field) *UrlMapsValidateCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *UrlMapsValidateCall) Do() (*UrlMapsValidateResponse, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.urlmapsvalidaterequest) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/global/urlMaps/{urlMap}/validate") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "urlMap": c.urlMap, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *UrlMapsValidateResponse - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Run static validation for the UrlMap. In particular, the tests of the provided UrlMap will be run. Calling this method does NOT create the UrlMap.", - // "httpMethod": "POST", - // "id": "compute.urlMaps.validate", - // "parameterOrder": [ - // "project", - // "urlMap" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "urlMap": { - // "description": "Name of the UrlMap resource to be validated as.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/global/urlMaps/{urlMap}/validate", - // "request": { - // "$ref": "UrlMapsValidateRequest" - // }, - // "response": { - // "$ref": "UrlMapsValidateResponse" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.zoneOperations.delete": - -type ZoneOperationsDeleteCall struct { - s *Service - project string - zone string - operation string - opt_ map[string]interface{} -} - -// Delete: Deletes the specified zone-specific operation resource. -func (r *ZoneOperationsService) Delete(project string, zone string, operation string) *ZoneOperationsDeleteCall { - c := &ZoneOperationsDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.operation = operation - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ZoneOperationsDeleteCall) Fields(s ...googleapi.Field) *ZoneOperationsDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ZoneOperationsDeleteCall) Do() error { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/operations/{operation}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("DELETE", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - "operation": c.operation, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return err - } - return nil - // { - // "description": "Deletes the specified zone-specific operation resource.", - // "httpMethod": "DELETE", - // "id": "compute.zoneOperations.delete", - // "parameterOrder": [ - // "project", - // "zone", - // "operation" - // ], - // "parameters": { - // "operation": { - // "description": "Name of the operation resource to delete.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/operations/{operation}", - // "scopes": [ - // "https://www.googleapis.com/auth/compute" - // ] - // } - -} - -// method id "compute.zoneOperations.get": - -type ZoneOperationsGetCall struct { - s *Service - project string - zone string - operation string - opt_ map[string]interface{} -} - -// Get: Retrieves the specified zone-specific operation resource. -func (r *ZoneOperationsService) Get(project string, zone string, operation string) *ZoneOperationsGetCall { - c := &ZoneOperationsGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - c.operation = operation - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ZoneOperationsGetCall) Fields(s ...googleapi.Field) *ZoneOperationsGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ZoneOperationsGetCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/operations/{operation}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - "operation": c.operation, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the specified zone-specific operation resource.", - // "httpMethod": "GET", - // "id": "compute.zoneOperations.get", - // "parameterOrder": [ - // "project", - // "zone", - // "operation" - // ], - // "parameters": { - // "operation": { - // "description": "Name of the operation resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/operations/{operation}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.zoneOperations.list": - -type ZoneOperationsListCall struct { - s *Service - project string - zone string - opt_ map[string]interface{} -} - -// List: Retrieves the list of operation resources contained within the -// specified zone. -func (r *ZoneOperationsService) List(project string, zone string) *ZoneOperationsListCall { - c := &ZoneOperationsListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *ZoneOperationsListCall) Filter(filter string) *ZoneOperationsListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *ZoneOperationsListCall) MaxResults(maxResults int64) *ZoneOperationsListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *ZoneOperationsListCall) PageToken(pageToken string) *ZoneOperationsListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ZoneOperationsListCall) Fields(s ...googleapi.Field) *ZoneOperationsListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ZoneOperationsListCall) Do() (*OperationList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}/operations") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *OperationList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of operation resources contained within the specified zone.", - // "httpMethod": "GET", - // "id": "compute.zoneOperations.list", - // "parameterOrder": [ - // "project", - // "zone" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone scoping this request.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}/operations", - // "response": { - // "$ref": "OperationList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.zones.get": - -type ZonesGetCall struct { - s *Service - project string - zone string - opt_ map[string]interface{} -} - -// Get: Returns the specified zone resource. -func (r *ZonesService) Get(project string, zone string) *ZonesGetCall { - c := &ZonesGetCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - c.zone = zone - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ZonesGetCall) Fields(s ...googleapi.Field) *ZonesGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ZonesGetCall) Do() (*Zone, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones/{zone}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - "zone": c.zone, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Zone - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Returns the specified zone resource.", - // "httpMethod": "GET", - // "id": "compute.zones.get", - // "parameterOrder": [ - // "project", - // "zone" - // ], - // "parameters": { - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // }, - // "zone": { - // "description": "Name of the zone resource to return.", - // "location": "path", - // "pattern": "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones/{zone}", - // "response": { - // "$ref": "Zone" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} - -// method id "compute.zones.list": - -type ZonesListCall struct { - s *Service - project string - opt_ map[string]interface{} -} - -// List: Retrieves the list of zone resources available to the specified -// project. -func (r *ZonesService) List(project string) *ZonesListCall { - c := &ZonesListCall{s: r.s, opt_: make(map[string]interface{})} - c.project = project - return c -} - -// Filter sets the optional parameter "filter": Filter expression for -// filtering listed resources. -func (c *ZonesListCall) Filter(filter string) *ZonesListCall { - c.opt_["filter"] = filter - return c -} - -// MaxResults sets the optional parameter "maxResults": Maximum count of -// results to be returned. Maximum value is 500 and default value is -// 500. -func (c *ZonesListCall) MaxResults(maxResults int64) *ZonesListCall { - c.opt_["maxResults"] = maxResults - return c -} - -// PageToken sets the optional parameter "pageToken": Tag returned by a -// previous list request truncated by maxResults. Used to continue a -// previous list request. -func (c *ZonesListCall) PageToken(pageToken string) *ZonesListCall { - c.opt_["pageToken"] = pageToken - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ZonesListCall) Fields(s ...googleapi.Field) *ZonesListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ZonesListCall) Do() (*ZoneList, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["filter"]; ok { - params.Set("filter", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["maxResults"]; ok { - params.Set("maxResults", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["pageToken"]; ok { - params.Set("pageToken", fmt.Sprintf("%v", v)) - } - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{project}/zones") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "project": c.project, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *ZoneList - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Retrieves the list of zone resources available to the specified project.", - // "httpMethod": "GET", - // "id": "compute.zones.list", - // "parameterOrder": [ - // "project" - // ], - // "parameters": { - // "filter": { - // "description": "Optional. Filter expression for filtering listed resources.", - // "location": "query", - // "type": "string" - // }, - // "maxResults": { - // "default": "500", - // "description": "Optional. Maximum count of results to be returned. Maximum value is 500 and default value is 500.", - // "format": "uint32", - // "location": "query", - // "maximum": "500", - // "minimum": "0", - // "type": "integer" - // }, - // "pageToken": { - // "description": "Optional. Tag returned by a previous list request truncated by maxResults. Used to continue a previous list request.", - // "location": "query", - // "type": "string" - // }, - // "project": { - // "description": "Name of the project scoping this request.", - // "location": "path", - // "pattern": "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?))", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{project}/zones", - // "response": { - // "$ref": "ZoneList" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/compute", - // "https://www.googleapis.com/auth/compute.readonly" - // ] - // } - -} diff --git a/Godeps/_workspace/src/code.google.com/p/google-api-go-client/container/v1beta1/v1beta1/container-api.json b/Godeps/_workspace/src/code.google.com/p/google-api-go-client/container/v1beta1/v1beta1/container-api.json deleted file mode 100644 index bca5a313cfe8..000000000000 --- a/Godeps/_workspace/src/code.google.com/p/google-api-go-client/container/v1beta1/v1beta1/container-api.json +++ /dev/null @@ -1,579 +0,0 @@ -{ - "kind": "discovery#restDescription", - "etag": "\"l66ggWbucbkBw9Lpos72oziyefE/ZrZBeDfQYPqAxFURJt0IhCOLUHQ\"", - "discoveryVersion": "v1", - "id": "container:v1beta1", - "name": "container", - "version": "v1beta1", - "revision": "20141103", - "title": "Google Container Engine API", - "description": "The Google Container Engine API is used for building and managing container based applications, powered by the open source Kubernetes technology.", - "ownerDomain": "google.com", - "ownerName": "Google", - "icons": { - "x16": "http://www.google.com/images/icons/product/search-16.gif", - "x32": "http://www.google.com/images/icons/product/search-32.gif" - }, - "protocol": "rest", - "baseUrl": "https://www.googleapis.com/container/v1beta1/projects/", - "basePath": "/container/v1beta1/projects/", - "rootUrl": "https://www.googleapis.com/", - "servicePath": "container/v1beta1/projects/", - "batchPath": "batch", - "parameters": { - "alt": { - "type": "string", - "description": "Data format for the response.", - "default": "json", - "enum": [ - "json" - ], - "enumDescriptions": [ - "Responses with Content-Type of application/json" - ], - "location": "query" - }, - "fields": { - "type": "string", - "description": "Selector specifying which fields to include in a partial response.", - "location": "query" - }, - "key": { - "type": "string", - "description": "API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.", - "location": "query" - }, - "oauth_token": { - "type": "string", - "description": "OAuth 2.0 token for the current user.", - "location": "query" - }, - "prettyPrint": { - "type": "boolean", - "description": "Returns response with indentations and line breaks.", - "default": "true", - "location": "query" - }, - "quotaUser": { - "type": "string", - "description": "Available to use for quota purposes for server-side applications. Can be any arbitrary string assigned to a user, but should not exceed 40 characters. Overrides userIp if both are provided.", - "location": "query" - }, - "userIp": { - "type": "string", - "description": "IP address of the site where the request originates. Use this if you want to enforce per-user limits.", - "location": "query" - } - }, - "auth": { - "oauth2": { - "scopes": { - "https://www.googleapis.com/auth/cloud-platform": { - "description": "View and manage your data across Google Cloud Platform services" - } - } - } - }, - "schemas": { - "Cluster": { - "id": "Cluster", - "type": "object", - "externalTypeName": "container.v1beta1.Cluster", - "properties": { - "clusterApiVersion": { - "type": "string", - "description": "The API version of the Kubernetes master and kubelets running in this cluster. Allowed value is 0.4.2, or leave blank to pick up the latest stable release." - }, - "containerIpv4Cidr": { - "type": "string", - "description": "[Output only] The IP addresses of the container pods in this cluster, in CIDR notation (e.g. 1.2.3.4/29)." - }, - "creationTimestamp": { - "type": "string", - "description": "[Output only] The time the cluster was created, in RFC3339 text format." - }, - "description": { - "type": "string", - "description": "An optional description of this cluster." - }, - "endpoint": { - "type": "string", - "description": "[Output only] The IP address of this cluster's Kubernetes master. The endpoint can be accessed from the internet at https://username:password@endpoint/.\n\nSee the masterAuth property of this resource for username and password information." - }, - "masterAuth": { - "$ref": "MasterAuth", - "description": "The HTTP basic authentication information for accessing the master. Because the master endpoint is open to the internet, you should create a strong password." - }, - "name": { - "type": "string", - "description": "The name of this cluster. The name must be unique within this project and zone, and can be up to 40 characters with the following restrictions: \n- Lowercase letters, numbers, and hyphens only.\n- Must start with a letter.\n- Must end with a number or a letter." - }, - "nodeConfig": { - "$ref": "NodeConfig", - "description": "The machine type and image to use for all nodes in this cluster. See the descriptions of the child properties of nodeConfig." - }, - "nodeRoutingPrefixSize": { - "type": "integer", - "description": "[Output only] The size of the address space on each node for hosting containers.", - "format": "int32" - }, - "numNodes": { - "type": "integer", - "description": "The number of nodes to create in this cluster. You must ensure that your Compute Engine resource quota is sufficient for this number of instances plus one (to include the master). You must also have available firewall and routes quota.", - "format": "int32" - }, - "servicesIpv4Cidr": { - "type": "string", - "description": "[Output only] The IP addresses of the Kubernetes services in this cluster, in CIDR notation (e.g. 1.2.3.4/29). Service addresses are always in the 10.0.0.0/16 range." - }, - "status": { - "type": "string", - "description": "[Output only] The current status of this cluster.", - "enum": [ - "error", - "provisioning", - "running", - "stopping" - ], - "enumDescriptions": [ - "", - "", - "", - "" - ] - }, - "statusMessage": { - "type": "string", - "description": "[Output only] Additional information about the current status of this cluster, if available." - }, - "zone": { - "type": "string", - "description": "[Output only] The name of the Google Compute Engine zone in which the cluster resides." - } - } - }, - "CreateClusterRequest": { - "id": "CreateClusterRequest", - "type": "object", - "externalTypeName": "container.v1beta1.CreateClusterRequest", - "properties": { - "cluster": { - "$ref": "Cluster", - "description": "A cluster resource." - } - } - }, - "ListAggregatedClustersResponse": { - "id": "ListAggregatedClustersResponse", - "type": "object", - "externalTypeName": "container.v1beta1.ListAggregatedClustersResponse", - "properties": { - "clusters": { - "type": "array", - "description": "A list of clusters in the project, across all zones.", - "items": { - "$ref": "Cluster" - } - } - } - }, - "ListAggregatedOperationsResponse": { - "id": "ListAggregatedOperationsResponse", - "type": "object", - "externalTypeName": "container.v1beta1.ListAggregatedOperationsResponse", - "properties": { - "operations": { - "type": "array", - "description": "A list of operations in the project, across all zones.", - "items": { - "$ref": "Operation" - } - } - } - }, - "ListClustersResponse": { - "id": "ListClustersResponse", - "type": "object", - "externalTypeName": "container.v1beta1.ListClustersResponse", - "properties": { - "clusters": { - "type": "array", - "description": "A list of clusters in the project in the specified zone.", - "items": { - "$ref": "Cluster" - } - } - } - }, - "ListOperationsResponse": { - "id": "ListOperationsResponse", - "type": "object", - "externalTypeName": "container.v1beta1.ListOperationsResponse", - "properties": { - "operations": { - "type": "array", - "description": "A list of operations in the project in the specified zone.", - "items": { - "$ref": "Operation" - } - } - } - }, - "MasterAuth": { - "id": "MasterAuth", - "type": "object", - "externalTypeName": "container.v1beta1.MasterAuth", - "properties": { - "password": { - "type": "string", - "description": "The password to use when accessing the Kubernetes master endpoint." - }, - "user": { - "type": "string", - "description": "The username to use when accessing the Kubernetes master endpoint." - } - } - }, - "NodeConfig": { - "id": "NodeConfig", - "type": "object", - "externalTypeName": "container.v1beta1.NodeConfig", - "properties": { - "machineType": { - "type": "string", - "description": "The name of a Google Compute Engine machine type (e.g. n1-standard-1).\n\nIf unspecified, the default machine type is n1-standard-1." - }, - "sourceImage": { - "type": "string", - "description": "The fully-specified name of a Google Compute Engine image. For example: https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/backports-debian-7-wheezy-vYYYYMMDD (where YYYMMDD is the version date).\n\nIf specifying an image, you are responsible for ensuring its compatibility with the Debian 7 backports image. We recommend leaving this field blank to accept the default backports-debian-7-wheezy value." - } - } - }, - "Operation": { - "id": "Operation", - "type": "object", - "description": "Defines the operation resource. All fields are output only.", - "externalTypeName": "container.v1beta1.Operation", - "properties": { - "errorMessage": { - "type": "string", - "description": "If an error has occurred, a textual description of the error." - }, - "name": { - "type": "string", - "description": "The server-assigned ID for this operation. If the operation is fulfilled upfront, it may not have a resource name." - }, - "operationType": { - "type": "string", - "description": "The operation type.", - "enum": [ - "createCluster", - "deleteCluster" - ], - "enumDescriptions": [ - "", - "" - ] - }, - "status": { - "type": "string", - "description": "The current status of the operation.", - "enum": [ - "done", - "pending", - "running" - ], - "enumDescriptions": [ - "", - "", - "" - ] - }, - "target": { - "type": "string", - "description": "[Optional] The URL of the cluster resource that this operation is associated with." - }, - "zone": { - "type": "string", - "description": "The name of the Google Compute Engine zone in which the operation is taking place." - } - } - } - }, - "resources": { - "projects": { - "resources": { - "clusters": { - "methods": { - "list": { - "id": "container.projects.clusters.list", - "path": "{projectId}/clusters", - "httpMethod": "GET", - "description": "Lists all clusters owned by a project across all zones.", - "parameters": { - "projectId": { - "type": "string", - "description": "The Google Developers Console project ID or project number.", - "required": true, - "location": "path" - } - }, - "parameterOrder": [ - "projectId" - ], - "response": { - "$ref": "ListAggregatedClustersResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform" - ] - } - } - }, - "operations": { - "methods": { - "list": { - "id": "container.projects.operations.list", - "path": "{projectId}/operations", - "httpMethod": "GET", - "description": "Lists all operations in a project, across all zones.", - "parameters": { - "projectId": { - "type": "string", - "description": "The Google Developers Console project ID or project number.", - "required": true, - "location": "path" - } - }, - "parameterOrder": [ - "projectId" - ], - "response": { - "$ref": "ListAggregatedOperationsResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform" - ] - } - } - }, - "zones": { - "resources": { - "clusters": { - "methods": { - "create": { - "id": "container.projects.zones.clusters.create", - "path": "{projectId}/zones/{zoneId}/clusters", - "httpMethod": "POST", - "description": "Creates a cluster, consisting of the specified number and type of Google Compute Engine instances, plus a Kubernetes master instance.\n\nThe cluster is created in the project's default network.\n\nA firewall is added that allows traffic into port 443 on the master, which enables HTTPS. A firewall and a route is added for each node to allow the containers on that node to communicate with all other instances in the cluster.\n\nFinally, a route named k8s-iproute-10-xx-0-0 is created to track that the cluster's 10.xx.0.0/16 CIDR has been assigned.", - "parameters": { - "projectId": { - "type": "string", - "description": "The Google Developers Console project ID or project number.", - "required": true, - "location": "path" - }, - "zoneId": { - "type": "string", - "description": "The name of the Google Compute Engine zone in which the cluster resides.", - "required": true, - "location": "path" - } - }, - "parameterOrder": [ - "projectId", - "zoneId" - ], - "request": { - "$ref": "CreateClusterRequest" - }, - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform" - ] - }, - "delete": { - "id": "container.projects.zones.clusters.delete", - "path": "{projectId}/zones/{zoneId}/clusters/{clusterId}", - "httpMethod": "DELETE", - "description": "Deletes the cluster, including the Kubernetes master and all worker nodes.\n\nFirewalls and routes that were configured at cluster creation are also deleted.", - "parameters": { - "clusterId": { - "type": "string", - "description": "The name of the cluster to delete.", - "required": true, - "location": "path" - }, - "projectId": { - "type": "string", - "description": "The Google Developers Console project ID or project number.", - "required": true, - "location": "path" - }, - "zoneId": { - "type": "string", - "description": "The name of the Google Compute Engine zone in which the cluster resides.", - "required": true, - "location": "path" - } - }, - "parameterOrder": [ - "projectId", - "zoneId", - "clusterId" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform" - ] - }, - "get": { - "id": "container.projects.zones.clusters.get", - "path": "{projectId}/zones/{zoneId}/clusters/{clusterId}", - "httpMethod": "GET", - "description": "Gets a specific cluster.", - "parameters": { - "clusterId": { - "type": "string", - "description": "The name of the cluster to retrieve.", - "required": true, - "location": "path" - }, - "projectId": { - "type": "string", - "description": "The Google Developers Console project ID or project number.", - "required": true, - "location": "path" - }, - "zoneId": { - "type": "string", - "description": "The name of the Google Compute Engine zone in which the cluster resides.", - "required": true, - "location": "path" - } - }, - "parameterOrder": [ - "projectId", - "zoneId", - "clusterId" - ], - "response": { - "$ref": "Cluster" - }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform" - ] - }, - "list": { - "id": "container.projects.zones.clusters.list", - "path": "{projectId}/zones/{zoneId}/clusters", - "httpMethod": "GET", - "description": "Lists all clusters owned by a project in the specified zone.", - "parameters": { - "projectId": { - "type": "string", - "description": "The Google Developers Console project ID or project number.", - "required": true, - "location": "path" - }, - "zoneId": { - "type": "string", - "description": "The name of the Google Compute Engine zone in which the cluster resides.", - "required": true, - "location": "path" - } - }, - "parameterOrder": [ - "projectId", - "zoneId" - ], - "response": { - "$ref": "ListClustersResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform" - ] - } - } - }, - "operations": { - "methods": { - "get": { - "id": "container.projects.zones.operations.get", - "path": "{projectId}/zones/{zoneId}/operations/{operationId}", - "httpMethod": "GET", - "description": "Gets the specified operation.", - "parameters": { - "operationId": { - "type": "string", - "description": "The server-assigned name of the operation.", - "required": true, - "location": "path" - }, - "projectId": { - "type": "string", - "description": "The Google Developers Console project ID or project number.", - "required": true, - "location": "path" - }, - "zoneId": { - "type": "string", - "description": "The name of the Google Compute Engine zone in which the operation resides. This is always the same zone as the cluster with which the operation is associated.", - "required": true, - "location": "path" - } - }, - "parameterOrder": [ - "projectId", - "zoneId", - "operationId" - ], - "response": { - "$ref": "Operation" - }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform" - ] - }, - "list": { - "id": "container.projects.zones.operations.list", - "path": "{projectId}/zones/{zoneId}/operations", - "httpMethod": "GET", - "description": "Lists all operations in a project in a specific zone.", - "parameters": { - "projectId": { - "type": "string", - "description": "The Google Developers Console project ID or project number.", - "required": true, - "location": "path" - }, - "zoneId": { - "type": "string", - "description": "The name of the Google Compute Engine zone to return operations for.", - "required": true, - "location": "path" - } - }, - "parameterOrder": [ - "projectId", - "zoneId" - ], - "response": { - "$ref": "ListOperationsResponse" - }, - "scopes": [ - "https://www.googleapis.com/auth/cloud-platform" - ] - } - } - } - } - } - } - } - } -} diff --git a/Godeps/_workspace/src/code.google.com/p/google-api-go-client/container/v1beta1/v1beta1/container-gen.go b/Godeps/_workspace/src/code.google.com/p/google-api-go-client/container/v1beta1/v1beta1/container-gen.go deleted file mode 100644 index c9fce64414bb..000000000000 --- a/Godeps/_workspace/src/code.google.com/p/google-api-go-client/container/v1beta1/v1beta1/container-gen.go +++ /dev/null @@ -1,1007 +0,0 @@ -// Package container provides access to the Google Container Engine API. -// -// Usage example: -// -// import "code.google.com/p/google-api-go-client/container/v1beta1" -// ... -// containerService, err := container.New(oauthHttpClient) -package container - -import ( - "bytes" - "code.google.com/p/google-api-go-client/googleapi" - "encoding/json" - "errors" - "fmt" - "io" - "net/http" - "net/url" - "strconv" - "strings" -) - -// Always reference these packages, just in case the auto-generated code -// below doesn't. -var _ = bytes.NewBuffer -var _ = strconv.Itoa -var _ = fmt.Sprintf -var _ = json.NewDecoder -var _ = io.Copy -var _ = url.Parse -var _ = googleapi.Version -var _ = errors.New -var _ = strings.Replace - -const apiId = "container:v1beta1" -const apiName = "container" -const apiVersion = "v1beta1" -const basePath = "https://www.googleapis.com/container/v1beta1/projects/" - -// OAuth2 scopes used by this API. -const ( - // View and manage your data across Google Cloud Platform services - CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform" -) - -func New(client *http.Client) (*Service, error) { - if client == nil { - return nil, errors.New("client is nil") - } - s := &Service{client: client, BasePath: basePath} - s.Projects = NewProjectsService(s) - return s, nil -} - -type Service struct { - client *http.Client - BasePath string // API endpoint base URL - - Projects *ProjectsService -} - -func NewProjectsService(s *Service) *ProjectsService { - rs := &ProjectsService{s: s} - rs.Clusters = NewProjectsClustersService(s) - rs.Operations = NewProjectsOperationsService(s) - rs.Zones = NewProjectsZonesService(s) - return rs -} - -type ProjectsService struct { - s *Service - - Clusters *ProjectsClustersService - - Operations *ProjectsOperationsService - - Zones *ProjectsZonesService -} - -func NewProjectsClustersService(s *Service) *ProjectsClustersService { - rs := &ProjectsClustersService{s: s} - return rs -} - -type ProjectsClustersService struct { - s *Service -} - -func NewProjectsOperationsService(s *Service) *ProjectsOperationsService { - rs := &ProjectsOperationsService{s: s} - return rs -} - -type ProjectsOperationsService struct { - s *Service -} - -func NewProjectsZonesService(s *Service) *ProjectsZonesService { - rs := &ProjectsZonesService{s: s} - rs.Clusters = NewProjectsZonesClustersService(s) - rs.Operations = NewProjectsZonesOperationsService(s) - return rs -} - -type ProjectsZonesService struct { - s *Service - - Clusters *ProjectsZonesClustersService - - Operations *ProjectsZonesOperationsService -} - -func NewProjectsZonesClustersService(s *Service) *ProjectsZonesClustersService { - rs := &ProjectsZonesClustersService{s: s} - return rs -} - -type ProjectsZonesClustersService struct { - s *Service -} - -func NewProjectsZonesOperationsService(s *Service) *ProjectsZonesOperationsService { - rs := &ProjectsZonesOperationsService{s: s} - return rs -} - -type ProjectsZonesOperationsService struct { - s *Service -} - -type Cluster struct { - // ClusterApiVersion: The API version of the Kubernetes master and - // kubelets running in this cluster. Allowed value is 0.4.2, or leave - // blank to pick up the latest stable release. - ClusterApiVersion string `json:"clusterApiVersion,omitempty"` - - // ContainerIpv4Cidr: [Output only] The IP addresses of the container - // pods in this cluster, in CIDR notation (e.g. 1.2.3.4/29). - ContainerIpv4Cidr string `json:"containerIpv4Cidr,omitempty"` - - // CreationTimestamp: [Output only] The time the cluster was created, in - // RFC3339 text format. - CreationTimestamp string `json:"creationTimestamp,omitempty"` - - // Description: An optional description of this cluster. - Description string `json:"description,omitempty"` - - // Endpoint: [Output only] The IP address of this cluster's Kubernetes - // master. The endpoint can be accessed from the internet at - // https://username:password@endpoint/. - // - // See the masterAuth property of - // this resource for username and password information. - Endpoint string `json:"endpoint,omitempty"` - - // MasterAuth: The HTTP basic authentication information for accessing - // the master. Because the master endpoint is open to the internet, you - // should create a strong password. - MasterAuth *MasterAuth `json:"masterAuth,omitempty"` - - // Name: The name of this cluster. The name must be unique within this - // project and zone, and can be up to 40 characters with the following - // restrictions: - // - Lowercase letters, numbers, and hyphens only. - // - - // Must start with a letter. - // - Must end with a number or a letter. - Name string `json:"name,omitempty"` - - // NodeConfig: The machine type and image to use for all nodes in this - // cluster. See the descriptions of the child properties of nodeConfig. - NodeConfig *NodeConfig `json:"nodeConfig,omitempty"` - - // NodeRoutingPrefixSize: [Output only] The size of the address space on - // each node for hosting containers. - NodeRoutingPrefixSize int64 `json:"nodeRoutingPrefixSize,omitempty"` - - // NumNodes: The number of nodes to create in this cluster. You must - // ensure that your Compute Engine resource quota is sufficient for this - // number of instances plus one (to include the master). You must also - // have available firewall and routes quota. - NumNodes int64 `json:"numNodes,omitempty"` - - // ServicesIpv4Cidr: [Output only] The IP addresses of the Kubernetes - // services in this cluster, in CIDR notation (e.g. 1.2.3.4/29). - // Service addresses are always in the 10.0.0.0/16 range. - ServicesIpv4Cidr string `json:"servicesIpv4Cidr,omitempty"` - - // Status: [Output only] The current status of this cluster. - Status string `json:"status,omitempty"` - - // StatusMessage: [Output only] Additional information about the current - // status of this cluster, if available. - StatusMessage string `json:"statusMessage,omitempty"` - - // Zone: [Output only] The name of the Google Compute Engine zone in - // which the cluster resides. - Zone string `json:"zone,omitempty"` -} - -type CreateClusterRequest struct { - // Cluster: A cluster resource. - Cluster *Cluster `json:"cluster,omitempty"` -} - -type ListAggregatedClustersResponse struct { - // Clusters: A list of clusters in the project, across all zones. - Clusters []*Cluster `json:"clusters,omitempty"` -} - -type ListAggregatedOperationsResponse struct { - // Operations: A list of operations in the project, across all zones. - Operations []*Operation `json:"operations,omitempty"` -} - -type ListClustersResponse struct { - // Clusters: A list of clusters in the project in the specified zone. - Clusters []*Cluster `json:"clusters,omitempty"` -} - -type ListOperationsResponse struct { - // Operations: A list of operations in the project in the specified - // zone. - Operations []*Operation `json:"operations,omitempty"` -} - -type MasterAuth struct { - // Password: The password to use when accessing the Kubernetes master - // endpoint. - Password string `json:"password,omitempty"` - - // User: The username to use when accessing the Kubernetes master - // endpoint. - User string `json:"user,omitempty"` -} - -type NodeConfig struct { - // MachineType: The name of a Google Compute Engine machine type (e.g. - // n1-standard-1). - // - // If unspecified, the default machine type is - // n1-standard-1. - MachineType string `json:"machineType,omitempty"` - - // SourceImage: The fully-specified name of a Google Compute Engine - // image. For example: - // https://www.googleapis.com/compute/v1/projects/debian-cloud/global/ima - // ges/backports-debian-7-wheezy-vYYYYMMDD (where YYYMMDD is the version - // date). - // - // If specifying an image, you are responsible for ensuring its - // compatibility with the Debian 7 backports image. We recommend leaving - // this field blank to accept the default backports-debian-7-wheezy - // value. - SourceImage string `json:"sourceImage,omitempty"` -} - -type Operation struct { - // ErrorMessage: If an error has occurred, a textual description of the - // error. - ErrorMessage string `json:"errorMessage,omitempty"` - - // Name: The server-assigned ID for this operation. If the operation is - // fulfilled upfront, it may not have a resource name. - Name string `json:"name,omitempty"` - - // OperationType: The operation type. - OperationType string `json:"operationType,omitempty"` - - // Status: The current status of the operation. - Status string `json:"status,omitempty"` - - // Target: [Optional] The URL of the cluster resource that this - // operation is associated with. - Target string `json:"target,omitempty"` - - // Zone: The name of the Google Compute Engine zone in which the - // operation is taking place. - Zone string `json:"zone,omitempty"` -} - -// method id "container.projects.clusters.list": - -type ProjectsClustersListCall struct { - s *Service - projectId string - opt_ map[string]interface{} -} - -// List: Lists all clusters owned by a project across all zones. -func (r *ProjectsClustersService) List(projectId string) *ProjectsClustersListCall { - c := &ProjectsClustersListCall{s: r.s, opt_: make(map[string]interface{})} - c.projectId = projectId - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ProjectsClustersListCall) Fields(s ...googleapi.Field) *ProjectsClustersListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ProjectsClustersListCall) Do() (*ListAggregatedClustersResponse, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{projectId}/clusters") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "projectId": c.projectId, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *ListAggregatedClustersResponse - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Lists all clusters owned by a project across all zones.", - // "httpMethod": "GET", - // "id": "container.projects.clusters.list", - // "parameterOrder": [ - // "projectId" - // ], - // "parameters": { - // "projectId": { - // "description": "The Google Developers Console project ID or project number.", - // "location": "path", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{projectId}/clusters", - // "response": { - // "$ref": "ListAggregatedClustersResponse" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/cloud-platform" - // ] - // } - -} - -// method id "container.projects.operations.list": - -type ProjectsOperationsListCall struct { - s *Service - projectId string - opt_ map[string]interface{} -} - -// List: Lists all operations in a project, across all zones. -func (r *ProjectsOperationsService) List(projectId string) *ProjectsOperationsListCall { - c := &ProjectsOperationsListCall{s: r.s, opt_: make(map[string]interface{})} - c.projectId = projectId - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ProjectsOperationsListCall) Fields(s ...googleapi.Field) *ProjectsOperationsListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ProjectsOperationsListCall) Do() (*ListAggregatedOperationsResponse, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{projectId}/operations") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "projectId": c.projectId, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *ListAggregatedOperationsResponse - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Lists all operations in a project, across all zones.", - // "httpMethod": "GET", - // "id": "container.projects.operations.list", - // "parameterOrder": [ - // "projectId" - // ], - // "parameters": { - // "projectId": { - // "description": "The Google Developers Console project ID or project number.", - // "location": "path", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{projectId}/operations", - // "response": { - // "$ref": "ListAggregatedOperationsResponse" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/cloud-platform" - // ] - // } - -} - -// method id "container.projects.zones.clusters.create": - -type ProjectsZonesClustersCreateCall struct { - s *Service - projectId string - zoneId string - createclusterrequest *CreateClusterRequest - opt_ map[string]interface{} -} - -// Create: Creates a cluster, consisting of the specified number and -// type of Google Compute Engine instances, plus a Kubernetes master -// instance. -// -// The cluster is created in the project's default -// network. -// -// A firewall is added that allows traffic into port 443 on -// the master, which enables HTTPS. A firewall and a route is added for -// each node to allow the containers on that node to communicate with -// all other instances in the cluster. -// -// Finally, a route named -// k8s-iproute-10-xx-0-0 is created to track that the cluster's -// 10.xx.0.0/16 CIDR has been assigned. -func (r *ProjectsZonesClustersService) Create(projectId string, zoneId string, createclusterrequest *CreateClusterRequest) *ProjectsZonesClustersCreateCall { - c := &ProjectsZonesClustersCreateCall{s: r.s, opt_: make(map[string]interface{})} - c.projectId = projectId - c.zoneId = zoneId - c.createclusterrequest = createclusterrequest - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ProjectsZonesClustersCreateCall) Fields(s ...googleapi.Field) *ProjectsZonesClustersCreateCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ProjectsZonesClustersCreateCall) Do() (*Operation, error) { - var body io.Reader = nil - body, err := googleapi.WithoutDataWrapper.JSONReader(c.createclusterrequest) - if err != nil { - return nil, err - } - ctype := "application/json" - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{projectId}/zones/{zoneId}/clusters") - urls += "?" + params.Encode() - req, _ := http.NewRequest("POST", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "projectId": c.projectId, - "zoneId": c.zoneId, - }) - req.Header.Set("Content-Type", ctype) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Creates a cluster, consisting of the specified number and type of Google Compute Engine instances, plus a Kubernetes master instance.\n\nThe cluster is created in the project's default network.\n\nA firewall is added that allows traffic into port 443 on the master, which enables HTTPS. A firewall and a route is added for each node to allow the containers on that node to communicate with all other instances in the cluster.\n\nFinally, a route named k8s-iproute-10-xx-0-0 is created to track that the cluster's 10.xx.0.0/16 CIDR has been assigned.", - // "httpMethod": "POST", - // "id": "container.projects.zones.clusters.create", - // "parameterOrder": [ - // "projectId", - // "zoneId" - // ], - // "parameters": { - // "projectId": { - // "description": "The Google Developers Console project ID or project number.", - // "location": "path", - // "required": true, - // "type": "string" - // }, - // "zoneId": { - // "description": "The name of the Google Compute Engine zone in which the cluster resides.", - // "location": "path", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{projectId}/zones/{zoneId}/clusters", - // "request": { - // "$ref": "CreateClusterRequest" - // }, - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/cloud-platform" - // ] - // } - -} - -// method id "container.projects.zones.clusters.delete": - -type ProjectsZonesClustersDeleteCall struct { - s *Service - projectId string - zoneId string - clusterId string - opt_ map[string]interface{} -} - -// Delete: Deletes the cluster, including the Kubernetes master and all -// worker nodes. -// -// Firewalls and routes that were configured at cluster -// creation are also deleted. -func (r *ProjectsZonesClustersService) Delete(projectId string, zoneId string, clusterId string) *ProjectsZonesClustersDeleteCall { - c := &ProjectsZonesClustersDeleteCall{s: r.s, opt_: make(map[string]interface{})} - c.projectId = projectId - c.zoneId = zoneId - c.clusterId = clusterId - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ProjectsZonesClustersDeleteCall) Fields(s ...googleapi.Field) *ProjectsZonesClustersDeleteCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ProjectsZonesClustersDeleteCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{projectId}/zones/{zoneId}/clusters/{clusterId}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("DELETE", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "projectId": c.projectId, - "zoneId": c.zoneId, - "clusterId": c.clusterId, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Deletes the cluster, including the Kubernetes master and all worker nodes.\n\nFirewalls and routes that were configured at cluster creation are also deleted.", - // "httpMethod": "DELETE", - // "id": "container.projects.zones.clusters.delete", - // "parameterOrder": [ - // "projectId", - // "zoneId", - // "clusterId" - // ], - // "parameters": { - // "clusterId": { - // "description": "The name of the cluster to delete.", - // "location": "path", - // "required": true, - // "type": "string" - // }, - // "projectId": { - // "description": "The Google Developers Console project ID or project number.", - // "location": "path", - // "required": true, - // "type": "string" - // }, - // "zoneId": { - // "description": "The name of the Google Compute Engine zone in which the cluster resides.", - // "location": "path", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{projectId}/zones/{zoneId}/clusters/{clusterId}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/cloud-platform" - // ] - // } - -} - -// method id "container.projects.zones.clusters.get": - -type ProjectsZonesClustersGetCall struct { - s *Service - projectId string - zoneId string - clusterId string - opt_ map[string]interface{} -} - -// Get: Gets a specific cluster. -func (r *ProjectsZonesClustersService) Get(projectId string, zoneId string, clusterId string) *ProjectsZonesClustersGetCall { - c := &ProjectsZonesClustersGetCall{s: r.s, opt_: make(map[string]interface{})} - c.projectId = projectId - c.zoneId = zoneId - c.clusterId = clusterId - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ProjectsZonesClustersGetCall) Fields(s ...googleapi.Field) *ProjectsZonesClustersGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ProjectsZonesClustersGetCall) Do() (*Cluster, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{projectId}/zones/{zoneId}/clusters/{clusterId}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "projectId": c.projectId, - "zoneId": c.zoneId, - "clusterId": c.clusterId, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Cluster - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Gets a specific cluster.", - // "httpMethod": "GET", - // "id": "container.projects.zones.clusters.get", - // "parameterOrder": [ - // "projectId", - // "zoneId", - // "clusterId" - // ], - // "parameters": { - // "clusterId": { - // "description": "The name of the cluster to retrieve.", - // "location": "path", - // "required": true, - // "type": "string" - // }, - // "projectId": { - // "description": "The Google Developers Console project ID or project number.", - // "location": "path", - // "required": true, - // "type": "string" - // }, - // "zoneId": { - // "description": "The name of the Google Compute Engine zone in which the cluster resides.", - // "location": "path", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{projectId}/zones/{zoneId}/clusters/{clusterId}", - // "response": { - // "$ref": "Cluster" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/cloud-platform" - // ] - // } - -} - -// method id "container.projects.zones.clusters.list": - -type ProjectsZonesClustersListCall struct { - s *Service - projectId string - zoneId string - opt_ map[string]interface{} -} - -// List: Lists all clusters owned by a project in the specified zone. -func (r *ProjectsZonesClustersService) List(projectId string, zoneId string) *ProjectsZonesClustersListCall { - c := &ProjectsZonesClustersListCall{s: r.s, opt_: make(map[string]interface{})} - c.projectId = projectId - c.zoneId = zoneId - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ProjectsZonesClustersListCall) Fields(s ...googleapi.Field) *ProjectsZonesClustersListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ProjectsZonesClustersListCall) Do() (*ListClustersResponse, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{projectId}/zones/{zoneId}/clusters") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "projectId": c.projectId, - "zoneId": c.zoneId, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *ListClustersResponse - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Lists all clusters owned by a project in the specified zone.", - // "httpMethod": "GET", - // "id": "container.projects.zones.clusters.list", - // "parameterOrder": [ - // "projectId", - // "zoneId" - // ], - // "parameters": { - // "projectId": { - // "description": "The Google Developers Console project ID or project number.", - // "location": "path", - // "required": true, - // "type": "string" - // }, - // "zoneId": { - // "description": "The name of the Google Compute Engine zone in which the cluster resides.", - // "location": "path", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{projectId}/zones/{zoneId}/clusters", - // "response": { - // "$ref": "ListClustersResponse" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/cloud-platform" - // ] - // } - -} - -// method id "container.projects.zones.operations.get": - -type ProjectsZonesOperationsGetCall struct { - s *Service - projectId string - zoneId string - operationId string - opt_ map[string]interface{} -} - -// Get: Gets the specified operation. -func (r *ProjectsZonesOperationsService) Get(projectId string, zoneId string, operationId string) *ProjectsZonesOperationsGetCall { - c := &ProjectsZonesOperationsGetCall{s: r.s, opt_: make(map[string]interface{})} - c.projectId = projectId - c.zoneId = zoneId - c.operationId = operationId - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ProjectsZonesOperationsGetCall) Fields(s ...googleapi.Field) *ProjectsZonesOperationsGetCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ProjectsZonesOperationsGetCall) Do() (*Operation, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{projectId}/zones/{zoneId}/operations/{operationId}") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "projectId": c.projectId, - "zoneId": c.zoneId, - "operationId": c.operationId, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *Operation - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Gets the specified operation.", - // "httpMethod": "GET", - // "id": "container.projects.zones.operations.get", - // "parameterOrder": [ - // "projectId", - // "zoneId", - // "operationId" - // ], - // "parameters": { - // "operationId": { - // "description": "The server-assigned name of the operation.", - // "location": "path", - // "required": true, - // "type": "string" - // }, - // "projectId": { - // "description": "The Google Developers Console project ID or project number.", - // "location": "path", - // "required": true, - // "type": "string" - // }, - // "zoneId": { - // "description": "The name of the Google Compute Engine zone in which the operation resides. This is always the same zone as the cluster with which the operation is associated.", - // "location": "path", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{projectId}/zones/{zoneId}/operations/{operationId}", - // "response": { - // "$ref": "Operation" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/cloud-platform" - // ] - // } - -} - -// method id "container.projects.zones.operations.list": - -type ProjectsZonesOperationsListCall struct { - s *Service - projectId string - zoneId string - opt_ map[string]interface{} -} - -// List: Lists all operations in a project in a specific zone. -func (r *ProjectsZonesOperationsService) List(projectId string, zoneId string) *ProjectsZonesOperationsListCall { - c := &ProjectsZonesOperationsListCall{s: r.s, opt_: make(map[string]interface{})} - c.projectId = projectId - c.zoneId = zoneId - return c -} - -// Fields allows partial responses to be retrieved. -// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse -// for more information. -func (c *ProjectsZonesOperationsListCall) Fields(s ...googleapi.Field) *ProjectsZonesOperationsListCall { - c.opt_["fields"] = googleapi.CombineFields(s) - return c -} - -func (c *ProjectsZonesOperationsListCall) Do() (*ListOperationsResponse, error) { - var body io.Reader = nil - params := make(url.Values) - params.Set("alt", "json") - if v, ok := c.opt_["fields"]; ok { - params.Set("fields", fmt.Sprintf("%v", v)) - } - urls := googleapi.ResolveRelative(c.s.BasePath, "{projectId}/zones/{zoneId}/operations") - urls += "?" + params.Encode() - req, _ := http.NewRequest("GET", urls, body) - googleapi.Expand(req.URL, map[string]string{ - "projectId": c.projectId, - "zoneId": c.zoneId, - }) - req.Header.Set("User-Agent", "google-api-go-client/0.5") - res, err := c.s.client.Do(req) - if err != nil { - return nil, err - } - defer googleapi.CloseBody(res) - if err := googleapi.CheckResponse(res); err != nil { - return nil, err - } - var ret *ListOperationsResponse - if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { - return nil, err - } - return ret, nil - // { - // "description": "Lists all operations in a project in a specific zone.", - // "httpMethod": "GET", - // "id": "container.projects.zones.operations.list", - // "parameterOrder": [ - // "projectId", - // "zoneId" - // ], - // "parameters": { - // "projectId": { - // "description": "The Google Developers Console project ID or project number.", - // "location": "path", - // "required": true, - // "type": "string" - // }, - // "zoneId": { - // "description": "The name of the Google Compute Engine zone to return operations for.", - // "location": "path", - // "required": true, - // "type": "string" - // } - // }, - // "path": "{projectId}/zones/{zoneId}/operations", - // "response": { - // "$ref": "ListOperationsResponse" - // }, - // "scopes": [ - // "https://www.googleapis.com/auth/cloud-platform" - // ] - // } - -} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors/errors.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors/errors.go index 88df9357c6c7..930efe7dab2d 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors/errors.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors/errors.go @@ -25,6 +25,12 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/util/errors" ) +// HTTP Status codes not in the golang http package. +const ( + StatusUnprocessableEntity = 422 + StatusTooManyRequests = 429 +) + // StatusError is an error intended for consumption by a REST API server; it can also be // reconstructed by clients from a REST response. Public to allow easy type switches. type StatusError struct { @@ -134,7 +140,7 @@ func NewInvalid(kind, name string, errs ValidationErrorList) error { } return &StatusError{api.Status{ Status: api.StatusFailure, - Code: 422, // RFC 4918: StatusUnprocessableEntity + Code: StatusUnprocessableEntity, // RFC 4918: StatusUnprocessableEntity Reason: api.StatusReasonInvalid, Details: &api.StatusDetails{ Kind: kind, @@ -148,14 +154,10 @@ func NewInvalid(kind, name string, errs ValidationErrorList) error { // NewBadRequest creates an error that indicates that the request is invalid and can not be processed. func NewBadRequest(reason string) error { return &StatusError{api.Status{ - Status: api.StatusFailure, - Code: http.StatusBadRequest, - Reason: api.StatusReasonBadRequest, - Details: &api.StatusDetails{ - Causes: []api.StatusCause{ - {Message: reason}, - }, - }, + Status: api.StatusFailure, + Code: http.StatusBadRequest, + Reason: api.StatusReasonBadRequest, + Message: reason, }} } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors/validation.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors/validation.go index a204e348cecc..a3b4eddf8d9a 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors/validation.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors/validation.go @@ -84,14 +84,21 @@ type ValidationError struct { var _ error = &ValidationError{} func (v *ValidationError) Error() string { - s := spew.Sprintf("%s: %s '%+v'", v.Field, v.Type, v.BadValue) - if v.Detail != "" { + var s string + switch v.Type { + case ValidationErrorTypeRequired: + s = spew.Sprintf("%s: %s", v.Field, v.Type) + default: + s = spew.Sprintf("%s: %s '%+v'", v.Field, v.Type, v.BadValue) + } + if len(v.Detail) != 0 { s += fmt.Sprintf(": %s", v.Detail) } return s } // NewFieldRequired returns a *ValidationError indicating "value required" +// TODO: remove "value" func NewFieldRequired(field string, value interface{}) *ValidationError { return &ValidationError{ValidationErrorTypeRequired, field, value, ""} } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors/validation_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors/validation_test.go index cc643d0236ae..23fa2c5021d4 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors/validation_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors/validation_test.go @@ -71,7 +71,7 @@ func TestValidationErrorUsefulMessage(t *testing.T) { Inner interface{} KV map[string]int } - s = NewFieldRequired( + s = NewFieldInvalid( "foo", &complicated{ Baz: 1, @@ -79,11 +79,12 @@ func TestValidationErrorUsefulMessage(t *testing.T) { Inner: &complicated{Qux: "asdf"}, KV: map[string]int{"Billy": 2}, }, + "detail", ).Error() t.Logf("message: %v", s) for _, part := range []string{ - "foo", ValidationErrorTypeRequired.String(), - "Baz", "Qux", "Inner", "KV", + "foo", ValidationErrorTypeInvalid.String(), + "Baz", "Qux", "Inner", "KV", "detail", "1", "aoeu", "asdf", "Billy", "2", } { if !strings.Contains(s, part) { diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/helpers.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/helpers.go index 5dff4d7c02b4..e05538e86a38 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/helpers.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/helpers.go @@ -21,6 +21,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource" "github.com/GoogleCloudPlatform/kubernetes/pkg/conversion" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/davecgh/go-spew/spew" ) @@ -60,3 +61,15 @@ var Semantic = conversion.EqualitiesOrDie( return a.Amount.Cmp(b.Amount) == 0 }, ) + +var standardResources = util.NewStringSet( + string(ResourceMemory), + string(ResourceCPU), + string(ResourcePods), + string(ResourceQuotas), + string(ResourceServices), + string(ResourceReplicationControllers)) + +func IsStandardResourceName(str string) bool { + return standardResources.Has(str) +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/helpers_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/helpers_test.go index c8cde624c31c..4ff6dba37d29 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/helpers_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/helpers_test.go @@ -67,3 +67,21 @@ func TestSemantic(t *testing.T) { } } } + +func TestIsStandardResource(t *testing.T) { + testCases := []struct { + input string + output bool + }{ + {"cpu", true}, + {"memory", true}, + {"disk", false}, + {"blah", false}, + {"x.y.z", false}, + } + for i, tc := range testCases { + if IsStandardResourceName(tc.input) != tc.output { + t.Errorf("case[%d], expected: %t, got: %t", i, tc.output, !tc.output) + } + } +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest/latest_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest/latest_test.go index 894043841482..f0582b5a18dd 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest/latest_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest/latest_test.go @@ -18,128 +18,21 @@ package latest import ( "encoding/json" - "strconv" + "math/rand" "testing" internal "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + apitesting "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testing" _ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1" _ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2" - "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" - - docker "github.com/fsouza/go-dockerclient" - fuzz "github.com/google/gofuzz" -) - -// apiObjectFuzzer can randomly populate api objects. -var apiObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 1).Funcs( - func(j *internal.TypeMeta, c fuzz.Continue) { - // We have to customize the randomization of TypeMetas because their - // APIVersion and Kind must remain blank in memory. - j.APIVersion = "" - j.Kind = "" - }, - func(j *internal.ObjectMeta, c fuzz.Continue) { - j.Name = c.RandString() - j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) - j.SelfLink = c.RandString() - - var sec, nsec int64 - c.Fuzz(&sec) - c.Fuzz(&nsec) - j.CreationTimestamp = util.Unix(sec, nsec).Rfc3339Copy() - }, - func(j *internal.ListMeta, c fuzz.Continue) { - j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) - j.SelfLink = c.RandString() - }, - func(j *internal.ObjectReference, c fuzz.Continue) { - // We have to customize the randomization of TypeMetas because their - // APIVersion and Kind must remain blank in memory. - j.APIVersion = c.RandString() - j.Kind = c.RandString() - j.Namespace = c.RandString() - j.Name = c.RandString() - j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) - j.FieldPath = c.RandString() - }, - func(j *internal.PodPhase, c fuzz.Continue) { - statuses := []internal.PodPhase{internal.PodPending, internal.PodRunning, internal.PodFailed, internal.PodUnknown} - *j = statuses[c.Rand.Intn(len(statuses))] - }, - func(j *internal.ReplicationControllerSpec, c fuzz.Continue) { - // TemplateRef must be nil for round trip - c.Fuzz(&j.Template) - if j.Template == nil { - // TODO: v1beta1/2 can't round trip a nil template correctly, fix by having v1beta1/2 - // conversion compare converted object to nil via DeepEqual - j.Template = &internal.PodTemplateSpec{} - } - j.Template.ObjectMeta = internal.ObjectMeta{Labels: j.Template.ObjectMeta.Labels} - j.Template.Spec.NodeSelector = nil - c.Fuzz(&j.Selector) - j.Replicas = int(c.RandUint64()) - }, - func(j *internal.ReplicationControllerStatus, c fuzz.Continue) { - // only replicas round trips - j.Replicas = int(c.RandUint64()) - }, - func(j *internal.List, c fuzz.Continue) { - c.Fuzz(&j.ListMeta) - c.Fuzz(&j.Items) - if j.Items == nil { - j.Items = []runtime.Object{} - } - }, - func(j *runtime.Object, c fuzz.Continue) { - if c.RandBool() { - *j = &runtime.Unknown{ - TypeMeta: runtime.TypeMeta{Kind: "Something", APIVersion: "unknown"}, - RawJSON: []byte(`{"apiVersion":"unknown","kind":"Something","someKey":"someValue"}`), - } - } else { - types := []runtime.Object{&internal.Pod{}, &internal.ReplicationController{}} - t := types[c.Rand.Intn(len(types))] - c.Fuzz(t) - *j = t - } - }, - func(intstr *util.IntOrString, c fuzz.Continue) { - // util.IntOrString will panic if its kind is set wrong. - if c.RandBool() { - intstr.Kind = util.IntstrInt - intstr.IntVal = int(c.RandUint64()) - intstr.StrVal = "" - } else { - intstr.Kind = util.IntstrString - intstr.IntVal = 0 - intstr.StrVal = c.RandString() - } - }, - func(pb map[docker.Port][]docker.PortBinding, c fuzz.Continue) { - // This is necessary because keys with nil values get omitted. - // TODO: Is this a bug? - pb[docker.Port(c.RandString())] = []docker.PortBinding{ - {c.RandString(), c.RandString()}, - {c.RandString(), c.RandString()}, - } - }, - func(pm map[string]docker.PortMapping, c fuzz.Continue) { - // This is necessary because keys with nil values get omitted. - // TODO: Is this a bug? - pm[c.RandString()] = docker.PortMapping{ - c.RandString(): c.RandString(), - } - }, - func(p *internal.PullPolicy, c fuzz.Continue) { - policies := []internal.PullPolicy{internal.PullAlways, internal.PullNever, internal.PullIfNotPresent} - *p = policies[c.Rand.Intn(len(policies))] - }, ) func TestInternalRoundTrip(t *testing.T) { latest := "v1beta2" + seed := rand.Int63() + apiObjectFuzzer := apitesting.FuzzerFor(t, "", rand.NewSource(seed)) for k := range internal.Scheme.KnownTypes("") { obj, err := internal.Scheme.New("", k) if err != nil { diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/register.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/register.go index 5c138425b187..b8638e442c29 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/register.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/register.go @@ -47,6 +47,11 @@ func init() { &BoundPod{}, &BoundPods{}, &List{}, + &LimitRange{}, + &LimitRangeList{}, + &ResourceQuota{}, + &ResourceQuotaList{}, + &ResourceQuotaUsage{}, ) // Legacy names are supported Scheme.AddKnownTypeWithName("", "Minion", &Node{}) @@ -77,3 +82,8 @@ func (*ContainerManifestList) IsAnAPIObject() {} func (*BoundPod) IsAnAPIObject() {} func (*BoundPods) IsAnAPIObject() {} func (*List) IsAnAPIObject() {} +func (*LimitRange) IsAnAPIObject() {} +func (*LimitRangeList) IsAnAPIObject() {} +func (*ResourceQuota) IsAnAPIObject() {} +func (*ResourceQuotaList) IsAnAPIObject() {} +func (*ResourceQuotaUsage) IsAnAPIObject() {} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/serialization_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/serialization_test.go index 7873819fee2d..656dc0e54356 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/serialization_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/serialization_test.go @@ -21,150 +21,25 @@ import ( "math/rand" "reflect" - "strconv" "testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta" - "github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource" + apitesting "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" - docker "github.com/fsouza/go-dockerclient" - fuzz "github.com/google/gofuzz" flag "github.com/spf13/pflag" - "speter.net/go/exp/math/dec/inf" ) var fuzzIters = flag.Int("fuzz_iters", 20, "How many fuzzing iterations to do.") -// fuzzerFor can randomly populate api objects that are destined for version. -func fuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer { - f := fuzz.New().NilChance(.5).NumElements(1, 1) - if src != nil { - f.RandSource(src) - } - f.Funcs( - func(j *runtime.PluginBase, c fuzz.Continue) { - // Do nothing; this struct has only a Kind field and it must stay blank in memory. - }, - func(j *runtime.TypeMeta, c fuzz.Continue) { - // We have to customize the randomization of TypeMetas because their - // APIVersion and Kind must remain blank in memory. - j.APIVersion = "" - j.Kind = "" - }, - func(j *api.TypeMeta, c fuzz.Continue) { - // We have to customize the randomization of TypeMetas because their - // APIVersion and Kind must remain blank in memory. - j.APIVersion = "" - j.Kind = "" - }, - func(j *api.ObjectMeta, c fuzz.Continue) { - j.Name = c.RandString() - j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) - j.SelfLink = c.RandString() - - var sec, nsec int64 - c.Fuzz(&sec) - c.Fuzz(&nsec) - j.CreationTimestamp = util.Unix(sec, nsec).Rfc3339Copy() - }, - func(j *api.ListMeta, c fuzz.Continue) { - j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) - j.SelfLink = c.RandString() - }, - func(j *api.PodPhase, c fuzz.Continue) { - statuses := []api.PodPhase{api.PodPending, api.PodRunning, api.PodFailed, api.PodUnknown} - *j = statuses[c.Rand.Intn(len(statuses))] - }, - func(j *api.ReplicationControllerSpec, c fuzz.Continue) { - // TemplateRef must be nil for round trip - c.Fuzz(&j.Template) - if j.Template == nil { - // TODO: v1beta1/2 can't round trip a nil template correctly, fix by having v1beta1/2 - // conversion compare converted object to nil via DeepEqual - j.Template = &api.PodTemplateSpec{} - } - j.Template.ObjectMeta = api.ObjectMeta{Labels: j.Template.ObjectMeta.Labels} - j.Template.Spec.NodeSelector = nil - c.Fuzz(&j.Selector) - j.Replicas = int(c.RandUint64()) - }, - func(j *api.ReplicationControllerStatus, c fuzz.Continue) { - // only replicas round trips - j.Replicas = int(c.RandUint64()) - }, - func(j *api.List, c fuzz.Continue) { - c.Fuzz(&j.ListMeta) - c.Fuzz(&j.Items) - if j.Items == nil { - j.Items = []runtime.Object{} - } - }, - func(j *runtime.Object, c fuzz.Continue) { - if c.RandBool() { - *j = &runtime.Unknown{ - TypeMeta: runtime.TypeMeta{Kind: "Something", APIVersion: "unknown"}, - RawJSON: []byte(`{"apiVersion":"unknown","kind":"Something","someKey":"someValue"}`), - } - } else { - types := []runtime.Object{&api.Pod{}, &api.ReplicationController{}} - t := types[c.Rand.Intn(len(types))] - c.Fuzz(t) - *j = t - } - }, - func(intstr *util.IntOrString, c fuzz.Continue) { - // util.IntOrString will panic if its kind is set wrong. - if c.RandBool() { - intstr.Kind = util.IntstrInt - intstr.IntVal = int(c.RandUint64()) - intstr.StrVal = "" - } else { - intstr.Kind = util.IntstrString - intstr.IntVal = 0 - intstr.StrVal = c.RandString() - } - }, - func(pb map[docker.Port][]docker.PortBinding, c fuzz.Continue) { - // This is necessary because keys with nil values get omitted. - // TODO: Is this a bug? - pb[docker.Port(c.RandString())] = []docker.PortBinding{ - {c.RandString(), c.RandString()}, - {c.RandString(), c.RandString()}, - } - }, - func(pm map[string]docker.PortMapping, c fuzz.Continue) { - // This is necessary because keys with nil values get omitted. - // TODO: Is this a bug? - pm[c.RandString()] = docker.PortMapping{ - c.RandString(): c.RandString(), - } - }, - func(q *resource.Quantity, c fuzz.Continue) { - // Real Quantity fuzz testing is done elsewhere; - // this limited subset of functionality survives - // round-tripping to v1beta1/2. - q.Amount = &inf.Dec{} - q.Format = resource.DecimalExponent - //q.Amount.SetScale(inf.Scale(-c.Intn(12))) - q.Amount.SetUnscaled(c.Int63n(1000)) - }, - func(p *api.PullPolicy, c fuzz.Continue) { - policies := []api.PullPolicy{api.PullAlways, api.PullNever, api.PullIfNotPresent} - *p = policies[c.Rand.Intn(len(policies))] - }, - ) - return f -} - func fuzzInternalObject(t *testing.T, forVersion string, item runtime.Object, seed int64) runtime.Object { - fuzzerFor(t, forVersion, rand.NewSource(seed)).Fuzz(item) + apitesting.FuzzerFor(t, forVersion, rand.NewSource(seed)).Fuzz(item) j, err := meta.TypeAccessor(item) if err != nil { @@ -317,7 +192,7 @@ const benchmarkSeed = 100 func BenchmarkEncode(b *testing.B) { pod := api.Pod{} - apiObjectFuzzer := fuzzerFor(nil, "", rand.NewSource(benchmarkSeed)) + apiObjectFuzzer := apitesting.FuzzerFor(nil, "", rand.NewSource(benchmarkSeed)) apiObjectFuzzer.Fuzz(&pod) for i := 0; i < b.N; i++ { latest.Codec.Encode(&pod) @@ -327,7 +202,7 @@ func BenchmarkEncode(b *testing.B) { // BenchmarkEncodeJSON provides a baseline for regular JSON encode performance func BenchmarkEncodeJSON(b *testing.B) { pod := api.Pod{} - apiObjectFuzzer := fuzzerFor(nil, "", rand.NewSource(benchmarkSeed)) + apiObjectFuzzer := apitesting.FuzzerFor(nil, "", rand.NewSource(benchmarkSeed)) apiObjectFuzzer.Fuzz(&pod) for i := 0; i < b.N; i++ { json.Marshal(&pod) @@ -336,7 +211,7 @@ func BenchmarkEncodeJSON(b *testing.B) { func BenchmarkDecode(b *testing.B) { pod := api.Pod{} - apiObjectFuzzer := fuzzerFor(nil, "", rand.NewSource(benchmarkSeed)) + apiObjectFuzzer := apitesting.FuzzerFor(nil, "", rand.NewSource(benchmarkSeed)) apiObjectFuzzer.Fuzz(&pod) data, _ := latest.Codec.Encode(&pod) for i := 0; i < b.N; i++ { @@ -346,7 +221,7 @@ func BenchmarkDecode(b *testing.B) { func BenchmarkDecodeInto(b *testing.B) { pod := api.Pod{} - apiObjectFuzzer := fuzzerFor(nil, "", rand.NewSource(benchmarkSeed)) + apiObjectFuzzer := apitesting.FuzzerFor(nil, "", rand.NewSource(benchmarkSeed)) apiObjectFuzzer.Fuzz(&pod) data, _ := latest.Codec.Encode(&pod) for i := 0; i < b.N; i++ { @@ -358,7 +233,7 @@ func BenchmarkDecodeInto(b *testing.B) { // BenchmarkDecodeJSON provides a baseline for regular JSON decode performance func BenchmarkDecodeJSON(b *testing.B) { pod := api.Pod{} - apiObjectFuzzer := fuzzerFor(nil, "", rand.NewSource(benchmarkSeed)) + apiObjectFuzzer := apitesting.FuzzerFor(nil, "", rand.NewSource(benchmarkSeed)) apiObjectFuzzer.Fuzz(&pod) data, _ := latest.Codec.Encode(&pod) for i := 0; i < b.N; i++ { diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/testing/fuzzer.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/testing/fuzzer.go new file mode 100644 index 000000000000..93008d7aa580 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/testing/fuzzer.go @@ -0,0 +1,162 @@ +/* +Copyright 2015 Google Inc. All rights reserved. + +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 testing + +import ( + "math/rand" + "strconv" + "testing" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource" + "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" + + "github.com/fsouza/go-dockerclient" + "github.com/google/gofuzz" + "speter.net/go/exp/math/dec/inf" +) + +// FuzzerFor can randomly populate api objects that are destined for version. +func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer { + f := fuzz.New().NilChance(.5).NumElements(1, 1) + if src != nil { + f.RandSource(src) + } + f.Funcs( + func(j *runtime.PluginBase, c fuzz.Continue) { + // Do nothing; this struct has only a Kind field and it must stay blank in memory. + }, + func(j *runtime.TypeMeta, c fuzz.Continue) { + // We have to customize the randomization of TypeMetas because their + // APIVersion and Kind must remain blank in memory. + j.APIVersion = "" + j.Kind = "" + }, + func(j *api.TypeMeta, c fuzz.Continue) { + // We have to customize the randomization of TypeMetas because their + // APIVersion and Kind must remain blank in memory. + j.APIVersion = "" + j.Kind = "" + }, + func(j *api.ObjectMeta, c fuzz.Continue) { + j.Name = c.RandString() + j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) + j.SelfLink = c.RandString() + + var sec, nsec int64 + c.Fuzz(&sec) + c.Fuzz(&nsec) + j.CreationTimestamp = util.Unix(sec, nsec).Rfc3339Copy() + }, + func(j *api.ObjectReference, c fuzz.Continue) { + // We have to customize the randomization of TypeMetas because their + // APIVersion and Kind must remain blank in memory. + j.APIVersion = c.RandString() + j.Kind = c.RandString() + j.Namespace = c.RandString() + j.Name = c.RandString() + j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) + j.FieldPath = c.RandString() + }, + func(j *api.ListMeta, c fuzz.Continue) { + j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) + j.SelfLink = c.RandString() + }, + func(j *api.PodPhase, c fuzz.Continue) { + statuses := []api.PodPhase{api.PodPending, api.PodRunning, api.PodFailed, api.PodUnknown} + *j = statuses[c.Rand.Intn(len(statuses))] + }, + func(j *api.ReplicationControllerSpec, c fuzz.Continue) { + // TemplateRef must be nil for round trip + c.Fuzz(&j.Template) + if j.Template == nil { + // TODO: v1beta1/2 can't round trip a nil template correctly, fix by having v1beta1/2 + // conversion compare converted object to nil via DeepEqual + j.Template = &api.PodTemplateSpec{} + } + j.Template.ObjectMeta = api.ObjectMeta{Labels: j.Template.ObjectMeta.Labels} + c.Fuzz(&j.Selector) + j.Replicas = int(c.RandUint64()) + }, + func(j *api.ReplicationControllerStatus, c fuzz.Continue) { + // only replicas round trips + j.Replicas = int(c.RandUint64()) + }, + func(j *api.List, c fuzz.Continue) { + c.Fuzz(&j.ListMeta) + c.Fuzz(&j.Items) + if j.Items == nil { + j.Items = []runtime.Object{} + } + }, + func(j *runtime.Object, c fuzz.Continue) { + if c.RandBool() { + *j = &runtime.Unknown{ + TypeMeta: runtime.TypeMeta{Kind: "Something", APIVersion: "unknown"}, + RawJSON: []byte(`{"apiVersion":"unknown","kind":"Something","someKey":"someValue"}`), + } + } else { + types := []runtime.Object{&api.Pod{}, &api.ReplicationController{}} + t := types[c.Rand.Intn(len(types))] + c.Fuzz(t) + *j = t + } + }, + func(intstr *util.IntOrString, c fuzz.Continue) { + // util.IntOrString will panic if its kind is set wrong. + if c.RandBool() { + intstr.Kind = util.IntstrInt + intstr.IntVal = int(c.RandUint64()) + intstr.StrVal = "" + } else { + intstr.Kind = util.IntstrString + intstr.IntVal = 0 + intstr.StrVal = c.RandString() + } + }, + func(pb map[docker.Port][]docker.PortBinding, c fuzz.Continue) { + // This is necessary because keys with nil values get omitted. + // TODO: Is this a bug? + pb[docker.Port(c.RandString())] = []docker.PortBinding{ + {c.RandString(), c.RandString()}, + {c.RandString(), c.RandString()}, + } + }, + func(pm map[string]docker.PortMapping, c fuzz.Continue) { + // This is necessary because keys with nil values get omitted. + // TODO: Is this a bug? + pm[c.RandString()] = docker.PortMapping{ + c.RandString(): c.RandString(), + } + }, + func(q *resource.Quantity, c fuzz.Continue) { + // Real Quantity fuzz testing is done elsewhere; + // this limited subset of functionality survives + // round-tripping to v1beta1/2. + q.Amount = &inf.Dec{} + q.Format = resource.DecimalExponent + //q.Amount.SetScale(inf.Scale(-c.Intn(12))) + q.Amount.SetUnscaled(c.Int63n(1000)) + }, + func(p *api.PullPolicy, c fuzz.Continue) { + policies := []api.PullPolicy{api.PullAlways, api.PullNever, api.PullIfNotPresent} + *p = policies[c.Rand.Intn(len(policies))] + }, + ) + return f +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/types.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/types.go index 80b41de867bd..a9179a16b235 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/types.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/types.go @@ -273,15 +273,10 @@ type ExecAction struct { Command []string `json:"command,omitempty"` } -// LivenessProbe describes a liveness probe to be examined to the container. -// TODO: pass structured data to the actions, and document that data here. -type LivenessProbe struct { - // HTTPGetProbe parameters, required if Type == 'http' - HTTPGet *HTTPGetAction `json:"httpGet,omitempty"` - // TCPSocketProbe parameter, required if Type == 'tcp' - TCPSocket *TCPSocketAction `json:"tcpSocket,omitempty"` - // ExecProbe parameter, required if Type == 'exec' - Exec *ExecAction `json:"exec,omitempty"` +// Probe describes a liveness probe to be examined to the container. +type Probe struct { + // The action taken to determine the health of a container + Handler `json:",inline"` // Length of time before health checking is activated. In seconds. InitialDelaySeconds int64 `json:"initialDelaySeconds,omitempty"` } @@ -298,6 +293,17 @@ const ( PullIfNotPresent PullPolicy = "IfNotPresent" ) +// CapabilityType represent POSIX capabilities type +type CapabilityType string + +// Capabilities represent POSIX capabilities that can be added or removed to a running container. +type Capabilities struct { + // Added capabilities + Add []CapabilityType `json:"add,omitempty"` + // Removed capabilities + Drop []CapabilityType `json:"drop,omitempty"` +} + // Container represents a single container that is expected to be run on the host. type Container struct { // Required: This must be a DNS_LABEL. Each container in a pod must @@ -316,7 +322,7 @@ type Container struct { // Optional: Defaults to unlimited. CPU resource.Quantity `json:"cpu,omitempty"` VolumeMounts []VolumeMount `json:"volumeMounts,omitempty"` - LivenessProbe *LivenessProbe `json:"livenessProbe,omitempty"` + LivenessProbe *Probe `json:"livenessProbe,omitempty"` Lifecycle *Lifecycle `json:"lifecycle,omitempty"` // Optional: Defaults to /dev/termination-log TerminationMessagePath string `json:"terminationMessagePath,omitempty"` @@ -324,6 +330,8 @@ type Container struct { Privileged bool `json:"privileged,omitempty"` // Optional: Policy for pulling images for this container ImagePullPolicy PullPolicy `json:"imagePullPolicy"` + // Optional: Capabilities for container. + Capabilities Capabilities `json:"capabilities,omitempty"` } // Handler defines a specific action that should be taken @@ -334,6 +342,9 @@ type Handler struct { Exec *ExecAction `json:"exec,omitempty"` // HTTPGet specifies the http request to perform. HTTPGet *HTTPGetAction `json:"httpGet,omitempty"` + // TCPSocket specifies an action involving a TCP port. + // TODO: implement a realistic TCP lifecycle hook + TCPSocket *TCPSocketAction `json:"tcpSocket,omitempty"` } // Lifecycle describes actions that the management system should take in response to container lifecycle @@ -764,6 +775,8 @@ type NodeResources struct { type ResourceName string const ( + // The default compute resource namespace for all standard resource types. + DefaultResourceNamespace = "kubernetes.io" // CPU, in cores. (500m = .5 cores) ResourceCPU ResourceName = "cpu" // Memory, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024) @@ -821,12 +834,12 @@ type Status struct { TypeMeta `json:",inline"` ListMeta `json:"metadata,omitempty"` - // One of: "Success", "Failure", "Working" (for operations not yet completed) + // One of: "Success" or "Failure" Status string `json:"status,omitempty"` // A human-readable description of the status of this operation. Message string `json:"message,omitempty"` // A machine-readable description of why this operation is in the - // "Failure" or "Working" status. If this value is empty there + // "Failure" status. If this value is empty there // is no information available. A Reason clarifies an HTTP status // code but does not override it. Reason StatusReason `json:"reason,omitempty"` @@ -862,7 +875,6 @@ type StatusDetails struct { const ( StatusSuccess = "Success" StatusFailure = "Failure" - StatusWorking = "Working" ) // StatusReason is an enumeration of possible failure causes. Each StatusReason @@ -877,18 +889,6 @@ const ( // Status code 500. StatusReasonUnknown StatusReason = "" - // StatusReasonWorking means the server is processing this request and will complete - // at a future time. - // Details (optional): - // "kind" string - the name of the resource being referenced ("operation" today) - // "id" string - the identifier of the Operation resource where updates - // will be returned - // Headers (optional): - // "Location" - HTTP header populated with a URL that can retrieved the final - // status of this operation. - // Status code 202 - StatusReasonWorking StatusReason = "Working" - // StatusReasonForbidden means the server can be reached and understood the request, but refuses // to take any further action. It is the result of the server being configured to deny access for some reason // to the requested resource by the client. @@ -937,6 +937,12 @@ const ( // Status code 422 StatusReasonInvalid StatusReason = "Invalid" + // StatusReasonTimeout means that the request could not be completed within the given time. + // Clients can get this response only when they specified a timeout param in the request. + // The request might succeed with an increased value of timeout param. + // Status code 504 + StatusReasonTimeout StatusReason = "Timeout" + // StatusReasonBadRequest means that the request itself was invalid, because the request // doesn't make any sense, for example deleting a read-only object. This is different than // StatusReasonInvalid above which indicates that the API call could possibly succeed, but the @@ -979,7 +985,7 @@ type StatusCause struct { // CauseType is a machine readable value providing more detail about what // occured in a status response. An operation may have multiple causes for a -// status (whether Failure, Success, or Working). +// status (whether Failure or Success). type CauseType string const ( @@ -1136,3 +1142,104 @@ type List struct { Items []runtime.Object `json:"items"` } + +// A type of object that is limited +type LimitType string + +const ( + // Limit that applies to all pods in a namespace + LimitTypePod LimitType = "Pod" + // Limit that applies to all containers in a namespace + LimitTypeContainer LimitType = "Container" +) + +// LimitRangeItem defines a min/max usage limit for any resource that matches on kind +type LimitRangeItem struct { + // Type of resource that this limit applies to + Type LimitType `json:"type,omitempty"` + // Max usage constraints on this kind by resource name + Max ResourceList `json:"max,omitempty"` + // Min usage constraints on this kind by resource name + Min ResourceList `json:"min,omitempty"` +} + +// LimitRangeSpec defines a min/max usage limit for resources that match on kind +type LimitRangeSpec struct { + // Limits is the list of LimitRangeItem objects that are enforced + Limits []LimitRangeItem `json:"limits"` +} + +// LimitRange sets resource usage limits for each kind of resource in a Namespace +type LimitRange struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the limits enforced + Spec LimitRangeSpec `json:"spec,omitempty"` +} + +// LimitRangeList is a list of LimitRange items. +type LimitRangeList struct { + TypeMeta `json:",inline"` + ListMeta `json:"metadata,omitempty"` + + // Items is a list of LimitRange objects + Items []LimitRange `json:"items"` +} + +// The following identify resource constants for Kubernetes object types +const ( + // Pods, number + ResourcePods ResourceName = "pods" + // Services, number + ResourceServices ResourceName = "services" + // ReplicationControllers, number + ResourceReplicationControllers ResourceName = "replicationcontrollers" + // ResourceQuotas, number + ResourceQuotas ResourceName = "resourcequotas" +) + +// ResourceQuotaSpec defines the desired hard limits to enforce for Quota +type ResourceQuotaSpec struct { + // Hard is the set of desired hard limits for each named resource + Hard ResourceList `json:"hard,omitempty"` +} + +// ResourceQuotaStatus defines the enforced hard limits and observed use +type ResourceQuotaStatus struct { + // Hard is the set of enforced hard limits for each named resource + Hard ResourceList `json:"hard,omitempty"` + // Used is the current observed total usage of the resource in the namespace + Used ResourceList `json:"used,omitempty"` +} + +// ResourceQuota sets aggregate quota restrictions enforced per namespace +type ResourceQuota struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired quota + Spec ResourceQuotaSpec `json:"spec,omitempty"` + + // Status defines the actual enforced quota and its current usage + Status ResourceQuotaStatus `json:"status,omitempty"` +} + +// ResourceQuotaUsage captures system observed quota status per namespace +// It is used to enforce atomic updates of a backing ResourceQuota.Status field in storage +type ResourceQuotaUsage struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` + + // Status defines the actual enforced quota and its current usage + Status ResourceQuotaStatus `json:"status,omitempty"` +} + +// ResourceQuotaList is a list of ResourceQuota items +type ResourceQuotaList struct { + TypeMeta `json:",inline"` + ListMeta `json:"metadata,omitempty"` + + // Items is a list of ResourceQuota objects + Items []ResourceQuota `json:"items"` +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1/conversion.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1/conversion.go index eaeb5de893de..a205d054fec5 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1/conversion.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1/conversion.go @@ -410,6 +410,9 @@ func init() { return err } out.DesiredState.Host = in.Spec.Host + if err := s.Convert(&in.Spec.NodeSelector, &out.NodeSelector, 0); err != nil { + return err + } if err := s.Convert(&in.ObjectMeta.Labels, &out.Labels, 0); err != nil { return err } @@ -420,6 +423,9 @@ func init() { return err } out.Spec.Host = in.DesiredState.Host + if err := s.Convert(&in.NodeSelector, &out.Spec.NodeSelector, 0); err != nil { + return err + } if err := s.Convert(&in.Labels, &out.ObjectMeta.Labels, 0); err != nil { return err } @@ -562,7 +568,160 @@ func init() { out.Status.HostIP = in.HostIP return s.Convert(&in.NodeResources.Capacity, &out.Spec.Capacity, 0) }, - + func(in *newer.LimitRange, out *LimitRange, s conversion.Scope) error { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil { + return err + } + return nil + }, + func(in *LimitRange, out *newer.LimitRange, s conversion.Scope) error { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil { + return err + } + return nil + }, + func(in *newer.LimitRangeSpec, out *LimitRangeSpec, s conversion.Scope) error { + *out = LimitRangeSpec{} + out.Limits = make([]LimitRangeItem, len(in.Limits), len(in.Limits)) + for i := range in.Limits { + if err := s.Convert(&in.Limits[i], &out.Limits[i], 0); err != nil { + return err + } + } + return nil + }, + func(in *LimitRangeSpec, out *newer.LimitRangeSpec, s conversion.Scope) error { + *out = newer.LimitRangeSpec{} + out.Limits = make([]newer.LimitRangeItem, len(in.Limits), len(in.Limits)) + for i := range in.Limits { + if err := s.Convert(&in.Limits[i], &out.Limits[i], 0); err != nil { + return err + } + } + return nil + }, + func(in *newer.LimitRangeItem, out *LimitRangeItem, s conversion.Scope) error { + *out = LimitRangeItem{} + out.Type = LimitType(in.Type) + if err := s.Convert(&in.Max, &out.Max, 0); err != nil { + return err + } + if err := s.Convert(&in.Min, &out.Min, 0); err != nil { + return err + } + return nil + }, + func(in *LimitRangeItem, out *newer.LimitRangeItem, s conversion.Scope) error { + *out = newer.LimitRangeItem{} + out.Type = newer.LimitType(in.Type) + if err := s.Convert(&in.Max, &out.Max, 0); err != nil { + return err + } + if err := s.Convert(&in.Min, &out.Min, 0); err != nil { + return err + } + return nil + }, + func(in *newer.ResourceQuota, out *ResourceQuota, s conversion.Scope) error { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil { + return err + } + if err := s.Convert(&in.Status, &out.Status, 0); err != nil { + return err + } + return nil + }, + func(in *ResourceQuota, out *newer.ResourceQuota, s conversion.Scope) error { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil { + return err + } + if err := s.Convert(&in.Status, &out.Status, 0); err != nil { + return err + } + return nil + }, + func(in *newer.ResourceQuotaUsage, out *ResourceQuotaUsage, s conversion.Scope) error { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.Status, &out.Status, 0); err != nil { + return err + } + return nil + }, + func(in *ResourceQuotaUsage, out *newer.ResourceQuotaUsage, s conversion.Scope) error { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.Status, &out.Status, 0); err != nil { + return err + } + return nil + }, + func(in *newer.ResourceQuotaSpec, out *ResourceQuotaSpec, s conversion.Scope) error { + *out = ResourceQuotaSpec{} + if err := s.Convert(&in.Hard, &out.Hard, 0); err != nil { + return err + } + return nil + }, + func(in *ResourceQuotaSpec, out *newer.ResourceQuotaSpec, s conversion.Scope) error { + *out = newer.ResourceQuotaSpec{} + if err := s.Convert(&in.Hard, &out.Hard, 0); err != nil { + return err + } + return nil + }, + func(in *newer.ResourceQuotaStatus, out *ResourceQuotaStatus, s conversion.Scope) error { + *out = ResourceQuotaStatus{} + if err := s.Convert(&in.Hard, &out.Hard, 0); err != nil { + return err + } + if err := s.Convert(&in.Used, &out.Used, 0); err != nil { + return err + } + return nil + }, + func(in *ResourceQuotaStatus, out *newer.ResourceQuotaStatus, s conversion.Scope) error { + *out = newer.ResourceQuotaStatus{} + if err := s.Convert(&in.Hard, &out.Hard, 0); err != nil { + return err + } + if err := s.Convert(&in.Used, &out.Used, 0); err != nil { + return err + } + return nil + }, // Object ID <-> Name // TODO: amend the conversion package to allow overriding specific fields. func(in *ObjectReference, out *newer.ObjectReference, s conversion.Scope) error { @@ -740,6 +899,33 @@ func init() { } return nil }, + + func(in *newer.Probe, out *LivenessProbe, s conversion.Scope) error { + if err := s.Convert(&in.Exec, &out.Exec, 0); err != nil { + return err + } + if err := s.Convert(&in.HTTPGet, &out.HTTPGet, 0); err != nil { + return err + } + if err := s.Convert(&in.TCPSocket, &out.TCPSocket, 0); err != nil { + return err + } + out.InitialDelaySeconds = in.InitialDelaySeconds + return nil + }, + func(in *LivenessProbe, out *newer.Probe, s conversion.Scope) error { + if err := s.Convert(&in.Exec, &out.Exec, 0); err != nil { + return err + } + if err := s.Convert(&in.HTTPGet, &out.HTTPGet, 0); err != nil { + return err + } + if err := s.Convert(&in.TCPSocket, &out.TCPSocket, 0); err != nil { + return err + } + out.InitialDelaySeconds = in.InitialDelaySeconds + return nil + }, ) if err != nil { // If one of the conversion functions is malformed, detect it immediately. diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1/register.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1/register.go index 9d5e19bc8e87..17c917a48601 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1/register.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1/register.go @@ -48,6 +48,11 @@ func init() { &BoundPod{}, &BoundPods{}, &List{}, + &LimitRange{}, + &LimitRangeList{}, + &ResourceQuota{}, + &ResourceQuotaList{}, + &ResourceQuotaUsage{}, ) // Future names are supported api.Scheme.AddKnownTypeWithName("v1beta1", "Node", &Minion{}) @@ -78,3 +83,8 @@ func (*ContainerManifestList) IsAnAPIObject() {} func (*BoundPod) IsAnAPIObject() {} func (*BoundPods) IsAnAPIObject() {} func (*List) IsAnAPIObject() {} +func (*LimitRange) IsAnAPIObject() {} +func (*LimitRangeList) IsAnAPIObject() {} +func (*ResourceQuota) IsAnAPIObject() {} +func (*ResourceQuotaList) IsAnAPIObject() {} +func (*ResourceQuotaUsage) IsAnAPIObject() {} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1/types.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1/types.go index 1f11c12bbd7b..6940734702a3 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1/types.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1/types.go @@ -241,6 +241,17 @@ const ( PullIfNotPresent PullPolicy = "PullIfNotPresent" ) +// CapabilityType represent POSIX capabilities type +type CapabilityType string + +// Capabilities represent POSIX capabilities that can be added or removed to a running container. +type Capabilities struct { + // Added capabilities + Add []CapabilityType `json:"add,omitempty" description:"added capabilities"` + // Removed capabilities + Drop []CapabilityType `json:"drop,omitempty" description:"droped capabilities"` +} + // Container represents a single container that is expected to be run on the host. type Container struct { // Required: This must be a DNS_LABEL. Each container in a pod must @@ -267,17 +278,21 @@ type Container struct { Privileged bool `json:"privileged,omitempty" description:"whether or not the container is granted privileged status; defaults to false"` // Optional: Policy for pulling images for this container ImagePullPolicy PullPolicy `json:"imagePullPolicy" description:"image pull policy; one of PullAlways, PullNever, PullIfNotPresent; defaults to PullAlways if :latest tag is specified, or PullIfNotPresent otherwise"` + // Optional: Capabilities for container. + Capabilities Capabilities `json:"capabilities,omitempty" description:"capabilities for container"` } // Handler defines a specific action that should be taken -// TODO: merge this with liveness probing? // TODO: pass structured data to these actions, and document that data here. type Handler struct { // One and only one of the following should be specified. // Exec specifies the action to take. - Exec *ExecAction `json:"exec,omitempty" description:"exec-based hook handler"` + Exec *ExecAction `json:"exec,omitempty" description:"exec-based handler"` // HTTPGet specifies the http request to perform. - HTTPGet *HTTPGetAction `json:"httpGet,omitempty" description:"HTTP-based hook handler"` + HTTPGet *HTTPGetAction `json:"httpGet,omitempty" description:"HTTP-based handler"` + // TCPSocket specifies an action involving a TCP port. + // TODO: implement a realistic TCP lifecycle hook + TCPSocket *TCPSocketAction `json:"tcpSocket,omitempty" description:"TCP-based handler; TCP hooks not yet supported"` } // Lifecycle describes actions that the management system should take in response to container lifecycle @@ -457,6 +472,7 @@ type ReplicationController struct { // PodTemplate holds the information used for creating pods. type PodTemplate struct { DesiredState PodState `json:"desiredState,omitempty" description:"specification of the desired state of pods created from this template"` + NodeSelector map[string]string `json:"nodeSelector,omitempty" description:"a selector which must be true for the pod to fit on a node"` Labels map[string]string `json:"labels,omitempty" description:"map of string keys and values that can be used to organize and categorize the pods created from the template; must match the selector of the replication controller to which the template belongs; may match selectors of services"` } @@ -633,15 +649,15 @@ type Binding struct { // import both. type Status struct { TypeMeta `json:",inline"` - // One of: "Success", "Failure", "Working" (for operations not yet completed) - Status string `json:"status,omitempty" description:"status of the operation; either Working (not yet completed), Success, or Failure"` + // One of: "Success" or "Failure". + Status string `json:"status,omitempty" description:"status of the operation; either Success, or Failure"` // A human-readable description of the status of this operation. Message string `json:"message,omitempty" description:"human-readable description of the status of this operation"` // A machine-readable description of why this operation is in the - // "Failure" or "Working" status. If this value is empty there + // "Failure" status. If this value is empty there // is no information available. A Reason clarifies an HTTP status // code but does not override it. - Reason StatusReason `json:"reason,omitempty" description:"machine-readable description of why this operation is in the 'Failure' or 'Working' status; if this value is empty there is no information available; a reason clarifies an HTTP status code but does not override it"` + Reason StatusReason `json:"reason,omitempty" description:"machine-readable description of why this operation is in the 'Failure' status; if this value is empty there is no information available; a reason clarifies an HTTP status code but does not override it"` // Extended data associated with the reason. Each reason may define its // own extended details. This field is optional and the data returned // is not guaranteed to conform to any schema except that defined by @@ -673,7 +689,6 @@ type StatusDetails struct { const ( StatusSuccess = "Success" StatusFailure = "Failure" - StatusWorking = "Working" ) // StatusReason is an enumeration of possible failure causes. Each StatusReason @@ -688,18 +703,6 @@ const ( // Status code 500. StatusReasonUnknown StatusReason = "" - // StatusReasonWorking means the server is processing this request and will complete - // at a future time. - // Details (optional): - // "kind" string - the name of the resource being referenced ("operation" today) - // "id" string - the identifier of the Operation resource where updates - // will be returned - // Headers (optional): - // "Location" - HTTP header populated with a URL that can retrieved the final - // status of this operation. - // Status code 202 - StatusReasonWorking StatusReason = "Working" - // StatusReasonNotFound means one or more resources required for this operation // could not be found. // Details (optional): @@ -748,7 +751,7 @@ type StatusCause struct { // CauseType is a machine readable value providing more detail about what // occured in a status response. An operation may have multiple causes for a -// status (whether Failure, Success, or Working). +// status (whether Failure or Success). type CauseType string const ( @@ -903,3 +906,99 @@ type List struct { TypeMeta `json:",inline"` Items []runtime.RawExtension `json:"items" description:"list of objects"` } + +// A type of object that is limited +type LimitType string + +const ( + // Limit that applies to all pods in a namespace + LimitTypePod LimitType = "Pod" + // Limit that applies to all containers in a namespace + LimitTypeContainer LimitType = "Container" +) + +// LimitRangeItem defines a min/max usage limit for any resource that matches on kind +type LimitRangeItem struct { + // Type of resource that this limit applies to + Type LimitType `json:"type,omitempty"` + // Max usage constraints on this kind by resource name + Max ResourceList `json:"max,omitempty"` + // Min usage constraints on this kind by resource name + Min ResourceList `json:"min,omitempty"` +} + +// LimitRangeSpec defines a min/max usage limit for resources that match on kind +type LimitRangeSpec struct { + // Limits is the list of LimitRangeItem objects that are enforced + Limits []LimitRangeItem `json:"limits"` +} + +// LimitRange sets resource usage limits for each kind of resource in a Namespace +type LimitRange struct { + TypeMeta `json:",inline"` + + // Spec defines the limits enforced + Spec LimitRangeSpec `json:"spec,omitempty"` +} + +// LimitRangeList is a list of LimitRange items. +type LimitRangeList struct { + TypeMeta `json:",inline"` + + // Items is a list of LimitRange objects + Items []LimitRange `json:"items"` +} + +// The following identify resource constants for Kubernetes object types +const ( + // Pods, number + ResourcePods ResourceName = "pods" + // Services, number + ResourceServices ResourceName = "services" + // ReplicationControllers, number + ResourceReplicationControllers ResourceName = "replicationcontrollers" + // ResourceQuotas, number + ResourceQuotas ResourceName = "resourcequotas" +) + +// ResourceQuotaSpec defines the desired hard limits to enforce for Quota +type ResourceQuotaSpec struct { + // Hard is the set of desired hard limits for each named resource + Hard ResourceList `json:"hard,omitempty"` +} + +// ResourceQuotaStatus defines the enforced hard limits and observed use +type ResourceQuotaStatus struct { + // Hard is the set of enforced hard limits for each named resource + Hard ResourceList `json:"hard,omitempty"` + // Used is the current observed total usage of the resource in the namespace + Used ResourceList `json:"used,omitempty"` +} + +// ResourceQuota sets aggregate quota restrictions enforced per namespace +type ResourceQuota struct { + TypeMeta `json:",inline"` + + // Spec defines the desired quota + Spec ResourceQuotaSpec `json:"spec,omitempty"` + + // Status defines the actual enforced quota and its current usage + Status ResourceQuotaStatus `json:"status,omitempty"` +} + +// ResourceQuotaUsage captures system observed quota status per namespace +// It is used to enforce atomic updates of a backing ResourceQuota.Status field in storage +type ResourceQuotaUsage struct { + TypeMeta `json:",inline"` + + // Status defines the actual enforced quota and its current usage + Status ResourceQuotaStatus `json:"status,omitempty"` +} + +// ResourceQuotaList is a list of ResourceQuota items +type ResourceQuotaList struct { + TypeMeta `json:",inline"` + + // Items is a list of ResourceQuota objects + Items []ResourceQuota `json:"items"` +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2/conversion.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2/conversion.go index 3666e9314c84..4ae43951a2cc 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2/conversion.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2/conversion.go @@ -274,6 +274,9 @@ func init() { return err } out.DesiredState.Host = in.Spec.Host + if err := s.Convert(&in.Spec.NodeSelector, &out.NodeSelector, 0); err != nil { + return err + } if err := s.Convert(&in.ObjectMeta.Labels, &out.Labels, 0); err != nil { return err } @@ -284,6 +287,9 @@ func init() { return err } out.Spec.Host = in.DesiredState.Host + if err := s.Convert(&in.NodeSelector, &out.Spec.NodeSelector, 0); err != nil { + return err + } if err := s.Convert(&in.Labels, &out.ObjectMeta.Labels, 0); err != nil { return err } @@ -479,7 +485,160 @@ func init() { out.Status.HostIP = in.HostIP return s.Convert(&in.NodeResources.Capacity, &out.Spec.Capacity, 0) }, - + func(in *newer.LimitRange, out *LimitRange, s conversion.Scope) error { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil { + return err + } + return nil + }, + func(in *LimitRange, out *newer.LimitRange, s conversion.Scope) error { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil { + return err + } + return nil + }, + func(in *newer.LimitRangeSpec, out *LimitRangeSpec, s conversion.Scope) error { + *out = LimitRangeSpec{} + out.Limits = make([]LimitRangeItem, len(in.Limits), len(in.Limits)) + for i := range in.Limits { + if err := s.Convert(&in.Limits[i], &out.Limits[i], 0); err != nil { + return err + } + } + return nil + }, + func(in *LimitRangeSpec, out *newer.LimitRangeSpec, s conversion.Scope) error { + *out = newer.LimitRangeSpec{} + out.Limits = make([]newer.LimitRangeItem, len(in.Limits), len(in.Limits)) + for i := range in.Limits { + if err := s.Convert(&in.Limits[i], &out.Limits[i], 0); err != nil { + return err + } + } + return nil + }, + func(in *newer.LimitRangeItem, out *LimitRangeItem, s conversion.Scope) error { + *out = LimitRangeItem{} + out.Type = LimitType(in.Type) + if err := s.Convert(&in.Max, &out.Max, 0); err != nil { + return err + } + if err := s.Convert(&in.Min, &out.Min, 0); err != nil { + return err + } + return nil + }, + func(in *LimitRangeItem, out *newer.LimitRangeItem, s conversion.Scope) error { + *out = newer.LimitRangeItem{} + out.Type = newer.LimitType(in.Type) + if err := s.Convert(&in.Max, &out.Max, 0); err != nil { + return err + } + if err := s.Convert(&in.Min, &out.Min, 0); err != nil { + return err + } + return nil + }, + func(in *newer.ResourceQuota, out *ResourceQuota, s conversion.Scope) error { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil { + return err + } + if err := s.Convert(&in.Status, &out.Status, 0); err != nil { + return err + } + return nil + }, + func(in *ResourceQuota, out *newer.ResourceQuota, s conversion.Scope) error { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil { + return err + } + if err := s.Convert(&in.Status, &out.Status, 0); err != nil { + return err + } + return nil + }, + func(in *newer.ResourceQuotaUsage, out *ResourceQuotaUsage, s conversion.Scope) error { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.Status, &out.Status, 0); err != nil { + return err + } + return nil + }, + func(in *ResourceQuotaUsage, out *newer.ResourceQuotaUsage, s conversion.Scope) error { + if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil { + return err + } + if err := s.Convert(&in.Status, &out.Status, 0); err != nil { + return err + } + return nil + }, + func(in *newer.ResourceQuotaSpec, out *ResourceQuotaSpec, s conversion.Scope) error { + *out = ResourceQuotaSpec{} + if err := s.Convert(&in.Hard, &out.Hard, 0); err != nil { + return err + } + return nil + }, + func(in *ResourceQuotaSpec, out *newer.ResourceQuotaSpec, s conversion.Scope) error { + *out = newer.ResourceQuotaSpec{} + if err := s.Convert(&in.Hard, &out.Hard, 0); err != nil { + return err + } + return nil + }, + func(in *newer.ResourceQuotaStatus, out *ResourceQuotaStatus, s conversion.Scope) error { + *out = ResourceQuotaStatus{} + if err := s.Convert(&in.Hard, &out.Hard, 0); err != nil { + return err + } + if err := s.Convert(&in.Used, &out.Used, 0); err != nil { + return err + } + return nil + }, + func(in *ResourceQuotaStatus, out *newer.ResourceQuotaStatus, s conversion.Scope) error { + *out = newer.ResourceQuotaStatus{} + if err := s.Convert(&in.Hard, &out.Hard, 0); err != nil { + return err + } + if err := s.Convert(&in.Used, &out.Used, 0); err != nil { + return err + } + return nil + }, // Object ID <-> Name // TODO: amend the conversion package to allow overriding specific fields. func(in *ObjectReference, out *newer.ObjectReference, s conversion.Scope) error { @@ -653,6 +812,33 @@ func init() { } return nil }, + + func(in *newer.Probe, out *LivenessProbe, s conversion.Scope) error { + if err := s.Convert(&in.Exec, &out.Exec, 0); err != nil { + return err + } + if err := s.Convert(&in.HTTPGet, &out.HTTPGet, 0); err != nil { + return err + } + if err := s.Convert(&in.TCPSocket, &out.TCPSocket, 0); err != nil { + return err + } + out.InitialDelaySeconds = in.InitialDelaySeconds + return nil + }, + func(in *LivenessProbe, out *newer.Probe, s conversion.Scope) error { + if err := s.Convert(&in.Exec, &out.Exec, 0); err != nil { + return err + } + if err := s.Convert(&in.HTTPGet, &out.HTTPGet, 0); err != nil { + return err + } + if err := s.Convert(&in.TCPSocket, &out.TCPSocket, 0); err != nil { + return err + } + out.InitialDelaySeconds = in.InitialDelaySeconds + return nil + }, ) if err != nil { // If one of the conversion functions is malformed, detect it immediately. diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2/register.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2/register.go index 7682d9ad246d..ad447476c236 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2/register.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2/register.go @@ -48,6 +48,11 @@ func init() { &BoundPod{}, &BoundPods{}, &List{}, + &LimitRange{}, + &LimitRangeList{}, + &ResourceQuota{}, + &ResourceQuotaList{}, + &ResourceQuotaUsage{}, ) // Future names are supported api.Scheme.AddKnownTypeWithName("v1beta2", "Node", &Minion{}) @@ -78,3 +83,8 @@ func (*ContainerManifestList) IsAnAPIObject() {} func (*BoundPod) IsAnAPIObject() {} func (*BoundPods) IsAnAPIObject() {} func (*List) IsAnAPIObject() {} +func (*LimitRange) IsAnAPIObject() {} +func (*LimitRangeList) IsAnAPIObject() {} +func (*ResourceQuota) IsAnAPIObject() {} +func (*ResourceQuotaList) IsAnAPIObject() {} +func (*ResourceQuotaUsage) IsAnAPIObject() {} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2/types.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2/types.go index 3f1ef0bbacb1..052b4ee777e1 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2/types.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2/types.go @@ -205,6 +205,17 @@ const ( PullIfNotPresent PullPolicy = "PullIfNotPresent" ) +// CapabilityType represent POSIX capabilities type +type CapabilityType string + +// Capabilities represent POSIX capabilities that can be added or removed to a running container. +type Capabilities struct { + // Added capabilities + Add []CapabilityType `json:"add,omitempty" description:"added capabilities"` + // Removed capabilities + Drop []CapabilityType `json:"drop,omitempty" description:"droped capabilities"` +} + // Container represents a single container that is expected to be run on the host. type Container struct { // Required: This must be a DNS_LABEL. Each container in a pod must @@ -231,6 +242,8 @@ type Container struct { Privileged bool `json:"privileged,omitempty" description:"whether or not the container is granted privileged status; defaults to false"` // Optional: Policy for pulling images for this container ImagePullPolicy PullPolicy `json:"imagePullPolicy" description:"image pull policy; one of PullAlways, PullNever, PullIfNotPresent; defaults to PullAlways if :latest tag is specified, or PullIfNotPresent otherwise"` + // Optional: Capabilities for container. + Capabilities Capabilities `json:"capabilities,omitempty" description:"capabilities for container"` } // Handler defines a specific action that should be taken @@ -238,9 +251,12 @@ type Container struct { type Handler struct { // One and only one of the following should be specified. // Exec specifies the action to take. - Exec *ExecAction `json:"exec,omitempty" description:"exec-based hook handler"` + Exec *ExecAction `json:"exec,omitempty" description:"exec-based handler"` // HTTPGet specifies the http request to perform. - HTTPGet *HTTPGetAction `json:"httpGet,omitempty" description:"HTTP-based hook handler"` + HTTPGet *HTTPGetAction `json:"httpGet,omitempty" description:"HTTP-based handler"` + // TCPSocket specifies an action involving a TCP port. + // TODO: implement a realistic TCP lifecycle hook + TCPSocket *TCPSocketAction `json:"tcpSocket,omitempty" description:"TCP-based handler; TCP hooks not yet supported"` } // Lifecycle describes actions that the management system should take in response to container lifecycle @@ -420,6 +436,7 @@ type ReplicationController struct { // PodTemplate holds the information used for creating pods. type PodTemplate struct { DesiredState PodState `json:"desiredState,omitempty" description:"specification of the desired state of pods created from this template"` + NodeSelector map[string]string `json:"nodeSelector,omitempty" description:"a selector which must be true for the pod to fit on a node"` Labels map[string]string `json:"labels,omitempty" description:"map of string keys and values that can be used to organize and categorize the pods created from the template; must match the selector of the replication controller to which the template belongs; may match selectors of services"` } @@ -593,15 +610,15 @@ type Binding struct { // import both. type Status struct { TypeMeta `json:",inline"` - // One of: "Success", "Failure", "Working" (for operations not yet completed) - Status string `json:"status,omitempty" description:"status of the operation; either Working (not yet completed), Success, or Failure"` + // One of: "Success" or "Failure" + Status string `json:"status,omitempty" description:"status of the operation; either Success or Failure"` // A human-readable description of the status of this operation. Message string `json:"message,omitempty" description:"human-readable description of the status of this operation"` // A machine-readable description of why this operation is in the - // "Failure" or "Working" status. If this value is empty there + // "Failure" status. If this value is empty there // is no information available. A Reason clarifies an HTTP status // code but does not override it. - Reason StatusReason `json:"reason,omitempty" description:"machine-readable description of why this operation is in the 'Failure' or 'Working' status; if this value is empty there is no information available; a reason clarifies an HTTP status code but does not override it"` + Reason StatusReason `json:"reason,omitempty" description:"machine-readable description of why this operation is in the 'Failure' status; if this value is empty there is no information available; a reason clarifies an HTTP status code but does not override it"` // Extended data associated with the reason. Each reason may define its // own extended details. This field is optional and the data returned // is not guaranteed to conform to any schema except that defined by @@ -633,7 +650,6 @@ type StatusDetails struct { const ( StatusSuccess = "Success" StatusFailure = "Failure" - StatusWorking = "Working" ) // StatusReason is an enumeration of possible failure causes. Each StatusReason @@ -648,18 +664,6 @@ const ( // Status code 500. StatusReasonUnknown StatusReason = "" - // StatusReasonWorking means the server is processing this request and will complete - // at a future time. - // Details (optional): - // "kind" string - the name of the resource being referenced ("operation" today) - // "id" string - the identifier of the Operation resource where updates - // will be returned - // Headers (optional): - // "Location" - HTTP header populated with a URL that can retrieved the final - // status of this operation. - // Status code 202 - StatusReasonWorking StatusReason = "Working" - // StatusReasonNotFound means one or more resources required for this operation // could not be found. // Details (optional): @@ -721,7 +725,7 @@ type StatusCause struct { // CauseType is a machine readable value providing more detail about what // occured in a status response. An operation may have multiple causes for a -// status (whether Failure, Success, or Working). +// status (whether Failure or Success). type CauseType string const ( @@ -905,3 +909,99 @@ type List struct { TypeMeta `json:",inline"` Items []runtime.RawExtension `json:"items" description:"list of objects"` } + +// A type of object that is limited +type LimitType string + +const ( + // Limit that applies to all pods in a namespace + LimitTypePod LimitType = "Pod" + // Limit that applies to all containers in a namespace + LimitTypeContainer LimitType = "Container" +) + +// LimitRangeItem defines a min/max usage limit for any resource that matches on kind +type LimitRangeItem struct { + // Type of resource that this limit applies to + Type LimitType `json:"type,omitempty"` + // Max usage constraints on this kind by resource name + Max ResourceList `json:"max,omitempty"` + // Min usage constraints on this kind by resource name + Min ResourceList `json:"min,omitempty"` +} + +// LimitRangeSpec defines a min/max usage limit for resources that match on kind +type LimitRangeSpec struct { + // Limits is the list of LimitRangeItem objects that are enforced + Limits []LimitRangeItem `json:"limits"` +} + +// LimitRange sets resource usage limits for each kind of resource in a Namespace +type LimitRange struct { + TypeMeta `json:",inline"` + + // Spec defines the limits enforced + Spec LimitRangeSpec `json:"spec,omitempty"` +} + +// LimitRangeList is a list of LimitRange items. +type LimitRangeList struct { + TypeMeta `json:",inline"` + + // Items is a list of LimitRange objects + Items []LimitRange `json:"items"` +} + +// The following identify resource constants for Kubernetes object types +const ( + // Pods, number + ResourcePods ResourceName = "pods" + // Services, number + ResourceServices ResourceName = "services" + // ReplicationControllers, number + ResourceReplicationControllers ResourceName = "replicationcontrollers" + // ResourceQuotas, number + ResourceQuotas ResourceName = "resourcequotas" +) + +// ResourceQuotaSpec defines the desired hard limits to enforce for Quota +type ResourceQuotaSpec struct { + // Hard is the set of desired hard limits for each named resource + Hard ResourceList `json:"hard,omitempty"` +} + +// ResourceQuotaStatus defines the enforced hard limits and observed use +type ResourceQuotaStatus struct { + // Hard is the set of enforced hard limits for each named resource + Hard ResourceList `json:"hard,omitempty"` + // Used is the current observed total usage of the resource in the namespace + Used ResourceList `json:"used,omitempty"` +} + +// ResourceQuota sets aggregate quota restrictions enforced per namespace +type ResourceQuota struct { + TypeMeta `json:",inline"` + + // Spec defines the desired quota + Spec ResourceQuotaSpec `json:"spec,omitempty"` + + // Status defines the actual enforced quota and its current usage + Status ResourceQuotaStatus `json:"status,omitempty"` +} + +// ResourceQuotaUsage captures system observed quota status per namespace +// It is used to enforce atomic updates of a backing ResourceQuota.Status field in storage +type ResourceQuotaUsage struct { + TypeMeta `json:",inline"` + + // Status defines the actual enforced quota and its current usage + Status ResourceQuotaStatus `json:"status,omitempty"` +} + +// ResourceQuotaList is a list of ResourceQuota items +type ResourceQuotaList struct { + TypeMeta `json:",inline"` + + // Items is a list of ResourceQuota objects + Items []ResourceQuota `json:"items"` +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3/register.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3/register.go index 6594cb67e895..a1956cdc67b8 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3/register.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3/register.go @@ -48,6 +48,11 @@ func init() { &Event{}, &EventList{}, &List{}, + &LimitRange{}, + &LimitRangeList{}, + &ResourceQuota{}, + &ResourceQuotaList{}, + &ResourceQuotaUsage{}, ) // Legacy names are supported api.Scheme.AddKnownTypeWithName("v1beta3", "Minion", &Node{}) @@ -78,3 +83,8 @@ func (*OperationList) IsAnAPIObject() {} func (*Event) IsAnAPIObject() {} func (*EventList) IsAnAPIObject() {} func (*List) IsAnAPIObject() {} +func (*LimitRange) IsAnAPIObject() {} +func (*LimitRangeList) IsAnAPIObject() {} +func (*ResourceQuota) IsAnAPIObject() {} +func (*ResourceQuotaList) IsAnAPIObject() {} +func (*ResourceQuotaUsage) IsAnAPIObject() {} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3/types.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3/types.go index a02b1145a4fa..26c7a07478d6 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3/types.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3/types.go @@ -181,7 +181,7 @@ type VolumeSource struct { EmptyDir *EmptyDir `json:"emptyDir"` // GCEPersistentDisk represents a GCE Disk resource that is attached to a // kubelet's host machine and then exposed to the pod. - GCEPersistentDisk *GCEPersistentDisk `json:"persistentDisk"` + GCEPersistentDisk *GCEPersistentDisk `json:"gcePersistentDisk"` // GitRepo represents a git repository at a particular revision. GitRepo *GitRepo `json:"gitRepo"` } @@ -291,15 +291,10 @@ type ExecAction struct { Command []string `json:"command,omitempty"` } -// LivenessProbe describes how to probe a container for liveness. -// TODO: pass structured data to the actions, and document that data here. -type LivenessProbe struct { - // HTTPGetProbe parameters, required if Type == 'HTTP' - HTTPGet *HTTPGetAction `json:"httpGet,omitempty"` - // TCPSocketProbe parameter, required if Type == 'TCP' - TCPSocket *TCPSocketAction `json:"tcpSocket,omitempty"` - // ExecProbe parameter, required if Type == 'Exec' - Exec *ExecAction `json:"exec,omitempty"` +// Probe describes a liveness probe to be examined to the container. +type Probe struct { + // The action taken to determine the health of a container + Handler `json:",inline"` // Length of time before health checking is activated. In seconds. InitialDelaySeconds int64 `json:"initialDelaySeconds,omitempty"` } @@ -316,6 +311,17 @@ const ( PullIfNotPresent PullPolicy = "IfNotPresent" ) +// CapabilityType represent POSIX capabilities type +type CapabilityType string + +// Capabilities represent POSIX capabilities that can be added or removed to a running container. +type Capabilities struct { + // Added capabilities + Add []CapabilityType `json:"add,omitempty"` + // Removed capabilities + Drop []CapabilityType `json:"drop,omitempty"` +} + // Container represents a single container that is expected to be run on the host. type Container struct { // Required: This must be a DNS_LABEL. Each container in a pod must @@ -334,7 +340,7 @@ type Container struct { // Optional: Defaults to unlimited. Units: Cores. (500m == 1/2 core) CPU resource.Quantity `json:"cpu,omitempty"` VolumeMounts []VolumeMount `json:"volumeMounts,omitempty"` - LivenessProbe *LivenessProbe `json:"livenessProbe,omitempty"` + LivenessProbe *Probe `json:"livenessProbe,omitempty"` Lifecycle *Lifecycle `json:"lifecycle,omitempty"` // Optional: Defaults to /dev/termination-log TerminationMessagePath string `json:"terminationMessagePath,omitempty"` @@ -342,6 +348,8 @@ type Container struct { Privileged bool `json:"privileged,omitempty"` // Optional: Policy for pulling images for this container ImagePullPolicy PullPolicy `json:"imagePullPolicy"` + // Optional: Capabilities for container. + Capabilities Capabilities `json:"capabilities,omitempty"` } // Handler defines a specific action that should be taken @@ -352,6 +360,9 @@ type Handler struct { Exec *ExecAction `json:"exec,omitempty"` // HTTPGet specifies the http request to perform. HTTPGet *HTTPGetAction `json:"httpGet,omitempty"` + // TCPSocket specifies an action involving a TCP port. + // TODO: implement a realistic TCP lifecycle hook + TCPSocket *TCPSocketAction `json:"tcpSocket,omitempty"` } // Lifecycle describes actions that the management system should take in response to container lifecycle @@ -785,6 +796,8 @@ type NodeCondition struct { type ResourceName string const ( + // The default compute resource namespace for all standard resource types. + DefaultResourceNamespace = "kubernetes.io" // CPU, in cores. (500m = .5 cores) ResourceCPU ResourceName = "cpu" // Memory, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024) @@ -832,12 +845,12 @@ type Status struct { TypeMeta `json:",inline"` ListMeta `json:"metadata,omitempty"` - // One of: "Success", "Failure", "Working" (for operations not yet completed) + // One of: "Success" or "Failure" Status string `json:"status,omitempty"` // A human-readable description of the status of this operation. Message string `json:"message,omitempty"` // A machine-readable description of why this operation is in the - // "Failure" or "Working" status. If this value is empty there + // "Failure" status. If this value is empty there // is no information available. A Reason clarifies an HTTP status // code but does not override it. Reason StatusReason `json:"reason,omitempty"` @@ -872,7 +885,6 @@ type StatusDetails struct { const ( StatusSuccess = "Success" StatusFailure = "Failure" - StatusWorking = "Working" ) // StatusReason is an enumeration of possible failure causes. Each StatusReason @@ -887,18 +899,6 @@ const ( // Status code 500. StatusReasonUnknown StatusReason = "" - // StatusReasonWorking means the server is processing this request and will complete - // at a future time. - // Details (optional): - // "kind" string - the name of the resource being referenced ("operation" today) - // "id" string - the identifier of the Operation resource where updates - // will be returned - // Headers (optional): - // "Location" - HTTP header populated with a URL that can retrieved the final - // status of this operation. - // Status code 202 - StatusReasonWorking StatusReason = "Working" - // StatusReasonNotFound means one or more resources required for this operation // could not be found. // Details (optional): @@ -960,7 +960,7 @@ type StatusCause struct { // CauseType is a machine readable value providing more detail about what // occured in a status response. An operation may have multiple causes for a -// status (whether Failure, Success, or Working). +// status (whether Failure or Success). type CauseType string const ( @@ -1064,3 +1064,104 @@ type List struct { Items []runtime.RawExtension `json:"items" description:"list of objects"` } + +// A type of object that is limited +type LimitType string + +const ( + // Limit that applies to all pods in a namespace + LimitTypePod LimitType = "Pod" + // Limit that applies to all containers in a namespace + LimitTypeContainer LimitType = "Container" +) + +// LimitRangeItem defines a min/max usage limit for any resource that matches on kind +type LimitRangeItem struct { + // Type of resource that this limit applies to + Type LimitType `json:"type,omitempty"` + // Max usage constraints on this kind by resource name + Max ResourceList `json:"max,omitempty"` + // Min usage constraints on this kind by resource name + Min ResourceList `json:"min,omitempty"` +} + +// LimitRangeSpec defines a min/max usage limit for resources that match on kind +type LimitRangeSpec struct { + // Limits is the list of LimitRangeItem objects that are enforced + Limits []LimitRangeItem `json:"limits"` +} + +// LimitRange sets resource usage limits for each kind of resource in a Namespace +type LimitRange struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the limits enforced + Spec LimitRangeSpec `json:"spec,omitempty"` +} + +// LimitRangeList is a list of LimitRange items. +type LimitRangeList struct { + TypeMeta `json:",inline"` + ListMeta `json:"metadata,omitempty"` + + // Items is a list of LimitRange objects + Items []LimitRange `json:"items"` +} + +// The following identify resource constants for Kubernetes object types +const ( + // Pods, number + ResourcePods ResourceName = "pods" + // Services, number + ResourceServices ResourceName = "services" + // ReplicationControllers, number + ResourceReplicationControllers ResourceName = "replicationcontrollers" + // ResourceQuotas, number + ResourceQuotas ResourceName = "resourcequotas" +) + +// ResourceQuotaSpec defines the desired hard limits to enforce for Quota +type ResourceQuotaSpec struct { + // Hard is the set of desired hard limits for each named resource + Hard ResourceList `json:"hard,omitempty"` +} + +// ResourceQuotaStatus defines the enforced hard limits and observed use +type ResourceQuotaStatus struct { + // Hard is the set of enforced hard limits for each named resource + Hard ResourceList `json:"hard,omitempty"` + // Used is the current observed total usage of the resource in the namespace + Used ResourceList `json:"used,omitempty"` +} + +// ResourceQuota sets aggregate quota restrictions enforced per namespace +type ResourceQuota struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired quota + Spec ResourceQuotaSpec `json:"spec,omitempty"` + + // Status defines the actual enforced quota and its current usage + Status ResourceQuotaStatus `json:"status,omitempty"` +} + +// ResourceQuotaUsage captures system observed quota status per namespace +// It is used to enforce atomic updates of a backing ResourceQuota.Status field in storage +type ResourceQuotaUsage struct { + TypeMeta `json:",inline"` + ObjectMeta `json:"metadata,omitempty"` + + // Status defines the actual enforced quota and its current usage + Status ResourceQuotaStatus `json:"status,omitempty"` +} + +// ResourceQuotaList is a list of ResourceQuota items +type ResourceQuotaList struct { + TypeMeta `json:",inline"` + ListMeta `json:"metadata,omitempty"` + + // Items is a list of ResourceQuota objects + Items []ResourceQuota `json:"items"` +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation/schema_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation/schema_test.go index 30862e6cf001..c8a2c9a72b49 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation/schema_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation/schema_test.go @@ -18,16 +18,13 @@ package validation import ( "io/ioutil" - "strconv" + "math/rand" "testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + apitesting "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" - "github.com/GoogleCloudPlatform/kubernetes/pkg/util" - - docker "github.com/fsouza/go-dockerclient" - fuzz "github.com/google/gofuzz" ) func LoadSchemaForTest(file string) (Schema, error) { @@ -38,92 +35,6 @@ func LoadSchemaForTest(file string) (Schema, error) { return NewSwaggerSchemaFromBytes(data) } -// TODO: this is cloned from serialization_test.go, refactor to somewhere common like util -// apiObjectFuzzer can randomly populate api objects. -var apiObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 1).Funcs( - func(j *runtime.PluginBase, c fuzz.Continue) { - // Do nothing; this struct has only a Kind field and it must stay blank in memory. - }, - func(j *runtime.TypeMeta, c fuzz.Continue) { - // We have to customize the randomization of TypeMetas because their - // APIVersion and Kind must remain blank in memory. - j.APIVersion = "" - j.Kind = "" - }, - func(j *api.TypeMeta, c fuzz.Continue) { - // We have to customize the randomization of TypeMetas because their - // APIVersion and Kind must remain blank in memory. - j.APIVersion = "" - j.Kind = "" - }, - func(j *api.ObjectMeta, c fuzz.Continue) { - j.Name = c.RandString() - j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) - j.SelfLink = c.RandString() - - var sec, nsec int64 - c.Fuzz(&sec) - c.Fuzz(&nsec) - j.CreationTimestamp = util.Unix(sec, nsec).Rfc3339Copy() - }, - func(j *api.ListMeta, c fuzz.Continue) { - j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10) - j.SelfLink = c.RandString() - }, - func(j *api.PodPhase, c fuzz.Continue) { - statuses := []api.PodPhase{api.PodPending, api.PodRunning, api.PodFailed, api.PodUnknown} - *j = statuses[c.Rand.Intn(len(statuses))] - }, - func(j *api.ReplicationControllerSpec, c fuzz.Continue) { - // TemplateRef must be nil for round trip - c.Fuzz(&j.Template) - if j.Template == nil { - // TODO: v1beta1/2 can't round trip a nil template correctly, fix by having v1beta1/2 - // conversion compare converted object to nil via DeepEqual - j.Template = &api.PodTemplateSpec{} - } - j.Template.ObjectMeta = api.ObjectMeta{Labels: j.Template.ObjectMeta.Labels} - j.Template.Spec.NodeSelector = nil - c.Fuzz(&j.Selector) - j.Replicas = int(c.RandUint64()) - }, - func(j *api.ReplicationControllerStatus, c fuzz.Continue) { - // only replicas round trips - j.Replicas = int(c.RandUint64()) - }, - func(intstr *util.IntOrString, c fuzz.Continue) { - // util.IntOrString will panic if its kind is set wrong. - if c.RandBool() { - intstr.Kind = util.IntstrInt - intstr.IntVal = int(c.RandUint64()) - intstr.StrVal = "" - } else { - intstr.Kind = util.IntstrString - intstr.IntVal = 0 - intstr.StrVal = c.RandString() - } - }, - func(pb map[docker.Port][]docker.PortBinding, c fuzz.Continue) { - // This is necessary because keys with nil values get omitted. - // TODO: Is this a bug? - pb[docker.Port(c.RandString())] = []docker.PortBinding{ - {c.RandString(), c.RandString()}, - {c.RandString(), c.RandString()}, - } - }, - func(pm map[string]docker.PortMapping, c fuzz.Continue) { - // This is necessary because keys with nil values get omitted. - // TODO: Is this a bug? - pm[c.RandString()] = docker.PortMapping{ - c.RandString(): c.RandString(), - } - }, - func(p *api.PullPolicy, c fuzz.Continue) { - policies := []api.PullPolicy{api.PullAlways, api.PullNever, api.PullIfNotPresent} - *p = policies[c.Rand.Intn(len(policies))] - }, -) - func TestLoad(t *testing.T) { _, err := LoadSchemaForTest("v1beta1-swagger.json") if err != nil { @@ -145,6 +56,8 @@ func TestValidateOk(t *testing.T) { {obj: &api.ReplicationController{}}, } + seed := rand.Int63() + apiObjectFuzzer := apitesting.FuzzerFor(nil, "", rand.NewSource(seed)) for i := 0; i < 5; i++ { for _, test := range tests { testObj := test.obj diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation/validation.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation/validation.go index b3b0f01bb3cf..2271f8e20eaa 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation/validation.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation/validation.go @@ -29,9 +29,90 @@ import ( "github.com/golang/glog" ) -// ServiceLister is an abstract interface for testing. -type ServiceLister interface { - ListServices(api.Context) (*api.ServiceList, error) +// ValidateNameFunc validates that the provided name is valid for a given resource type. +// Not all resources have the same validation rules for names. +type ValidateNameFunc func(name string) (bool, string) + +// nameIsDNSSubdomain is a ValidateNameFunc for names that must be a DNS subdomain. +func nameIsDNSSubdomain(name string) (bool, string) { + if util.IsDNSSubdomain(name) { + return true, "" + } + return false, "name must be lowercase letters and numbers, with inline dashes or periods" +} + +// nameIsDNS952Label is a ValidateNameFunc for names that must be a DNS 952 label. +func nameIsDNS952Label(name string) (bool, string) { + if util.IsDNS952Label(name) { + return true, "" + } + return false, "name must be lowercase letters, numbers, and dashes" +} + +// ValidateObjectMeta validates an object's metadata. +func ValidateObjectMeta(meta *api.ObjectMeta, requiresNamespace bool, nameFn ValidateNameFunc) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + if len(meta.Name) == 0 { + allErrs = append(allErrs, errs.NewFieldRequired("name", meta.Name)) + } else { + if ok, qualifier := nameFn(meta.Name); !ok { + allErrs = append(allErrs, errs.NewFieldInvalid("name", meta.Name, qualifier)) + } + } + if requiresNamespace { + if len(meta.Namespace) == 0 { + allErrs = append(allErrs, errs.NewFieldRequired("namespace", meta.Namespace)) + } else if !util.IsDNSSubdomain(meta.Namespace) { + allErrs = append(allErrs, errs.NewFieldInvalid("namespace", meta.Namespace, "")) + } + } else { + if len(meta.Namespace) != 0 { + allErrs = append(allErrs, errs.NewFieldInvalid("namespace", meta.Namespace, "namespace is not allowed on this type")) + } + } + allErrs = append(allErrs, ValidateLabels(meta.Labels, "labels")...) + allErrs = append(allErrs, ValidateLabels(meta.Annotations, "annotations")...) + + // Clear self link internally + // TODO: move to its own area + meta.SelfLink = "" + + return allErrs +} + +// ValidateObjectMetaUpdate validates an object's metadata when updated +func ValidateObjectMetaUpdate(old, meta *api.ObjectMeta) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + + // in the event it is left empty, set it, to allow clients more flexibility + if len(meta.UID) == 0 { + meta.UID = old.UID + } + if meta.CreationTimestamp.IsZero() { + meta.CreationTimestamp = old.CreationTimestamp + } + + if old.Name != meta.Name { + allErrs = append(allErrs, errs.NewFieldInvalid("name", meta.Name, "field is immutable")) + } + if old.Namespace != meta.Namespace { + allErrs = append(allErrs, errs.NewFieldInvalid("namespace", meta.Namespace, "field is immutable")) + } + if old.UID != meta.UID { + allErrs = append(allErrs, errs.NewFieldInvalid("uid", meta.UID, "field is immutable")) + } + if old.CreationTimestamp != meta.CreationTimestamp { + allErrs = append(allErrs, errs.NewFieldInvalid("creationTimestamp", meta.CreationTimestamp, "field is immutable")) + } + + allErrs = append(allErrs, ValidateLabels(meta.Labels, "labels")...) + allErrs = append(allErrs, ValidateLabels(meta.Annotations, "annotations")...) + + // Clear self link internally + // TODO: move to its own area + meta.SelfLink = "" + + return allErrs } func validateVolumes(volumes []api.Volume) (util.StringSet, errs.ValidationErrorList) { @@ -387,18 +468,9 @@ func validateDNSPolicy(dnsPolicy *api.DNSPolicy) errs.ValidationErrorList { // ValidatePod tests if required fields in the pod are set. func ValidatePod(pod *api.Pod) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} - if len(pod.Name) == 0 { - allErrs = append(allErrs, errs.NewFieldRequired("name", pod.Name)) - } else if !util.IsDNSSubdomain(pod.Name) { - allErrs = append(allErrs, errs.NewFieldInvalid("name", pod.Name, "")) - } - if len(pod.Namespace) == 0 { - allErrs = append(allErrs, errs.NewFieldRequired("namespace", pod.Namespace)) - } else if !util.IsDNSSubdomain(pod.Namespace) { - allErrs = append(allErrs, errs.NewFieldInvalid("namespace", pod.Namespace, "")) - } + allErrs = append(allErrs, ValidateObjectMeta(&pod.ObjectMeta, true, nameIsDNSSubdomain).Prefix("metadata")...) allErrs = append(allErrs, ValidatePodSpec(&pod.Spec).Prefix("spec")...) - allErrs = append(allErrs, ValidateLabels(pod.Labels, "labels")...) + return allErrs } @@ -433,9 +505,7 @@ func ValidateLabels(labels map[string]string, field string) errs.ValidationError func ValidatePodUpdate(newPod, oldPod *api.Pod) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} - if newPod.Name != oldPod.Name { - allErrs = append(allErrs, errs.NewFieldInvalid("name", newPod.Name, "field is immutable")) - } + allErrs = append(allErrs, ValidateObjectMetaUpdate(&oldPod.ObjectMeta, &newPod.ObjectMeta).Prefix("metadata")...) if len(newPod.Spec.Containers) != len(oldPod.Spec.Containers) { allErrs = append(allErrs, errs.NewFieldInvalid("spec.containers", newPod.Spec.Containers, "may not add or remove containers")) @@ -453,22 +523,17 @@ func ValidatePodUpdate(newPod, oldPod *api.Pod) errs.ValidationErrorList { // TODO: a better error would include all immutable fields explicitly. allErrs = append(allErrs, errs.NewFieldInvalid("spec.containers", newPod.Spec.Containers, "some fields are immutable")) } + return allErrs } var supportedSessionAffinityType = util.NewStringSet(string(api.AffinityTypeClientIP), string(api.AffinityTypeNone)) // ValidateService tests if required fields in the service are set. -func ValidateService(service *api.Service, lister ServiceLister, ctx api.Context) errs.ValidationErrorList { +func ValidateService(service *api.Service) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} - if len(service.Name) == 0 { - allErrs = append(allErrs, errs.NewFieldRequired("name", service.Name)) - } else if !util.IsDNS952Label(service.Name) { - allErrs = append(allErrs, errs.NewFieldInvalid("name", service.Name, "")) - } - if !util.IsDNSSubdomain(service.Namespace) { - allErrs = append(allErrs, errs.NewFieldInvalid("namespace", service.Namespace, "")) - } + allErrs = append(allErrs, ValidateObjectMeta(&service.ObjectMeta, true, nameIsDNS952Label).Prefix("metadata")...) + if !util.IsValidPortNum(service.Spec.Port) { allErrs = append(allErrs, errs.NewFieldInvalid("spec.port", service.Spec.Port, "")) } @@ -481,23 +546,7 @@ func ValidateService(service *api.Service, lister ServiceLister, ctx api.Context if service.Spec.Selector != nil { allErrs = append(allErrs, ValidateLabels(service.Spec.Selector, "spec.selector")...) } - allErrs = append(allErrs, ValidateLabels(service.Labels, "labels")...) - if service.Spec.CreateExternalLoadBalancer { - services, err := lister.ListServices(ctx) - if err != nil { - allErrs = append(allErrs, errs.NewInternalError(err)) - } else { - for i := range services.Items { - if services.Items[i].Name != service.Name && - services.Items[i].Spec.CreateExternalLoadBalancer && - services.Items[i].Spec.Port == service.Spec.Port { - allErrs = append(allErrs, errs.NewConflict("service", service.Name, fmt.Errorf("port: %d is already in use", service.Spec.Port))) - break - } - } - } - } if service.Spec.SessionAffinity == "" { service.Spec.SessionAffinity = api.AffinityTypeNone } else if !supportedSessionAffinityType.Has(string(service.Spec.SessionAffinity)) { @@ -507,17 +556,35 @@ func ValidateService(service *api.Service, lister ServiceLister, ctx api.Context return allErrs } +// ValidateServiceUpdate tests if required fields in the service are set during an update +func ValidateServiceUpdate(oldService, service *api.Service) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, ValidateObjectMetaUpdate(&oldService.ObjectMeta, &service.ObjectMeta).Prefix("metadata")...) + + // TODO: PortalIP should be a Status field, since the system can set a value != to the user's value + // PortalIP can only be set, not unset. + if oldService.Spec.PortalIP != "" && service.Spec.PortalIP != oldService.Spec.PortalIP { + allErrs = append(allErrs, errs.NewFieldInvalid("spec.portalIP", service.Spec.PortalIP, "field is immutable")) + } + + return allErrs +} + // ValidateReplicationController tests if required fields in the replication controller are set. func ValidateReplicationController(controller *api.ReplicationController) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} - if len(controller.Name) == 0 { - allErrs = append(allErrs, errs.NewFieldRequired("name", controller.Name)) - } - if !util.IsDNSSubdomain(controller.Namespace) { - allErrs = append(allErrs, errs.NewFieldInvalid("namespace", controller.Namespace, "")) - } + allErrs = append(allErrs, ValidateObjectMeta(&controller.ObjectMeta, true, nameIsDNSSubdomain).Prefix("metadata")...) + allErrs = append(allErrs, ValidateReplicationControllerSpec(&controller.Spec).Prefix("spec")...) + + return allErrs +} + +// ValidateReplicationControllerUpdate tests if required fields in the replication controller are set. +func ValidateReplicationControllerUpdate(oldController, controller *api.ReplicationController) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + allErrs = append(allErrs, ValidateObjectMetaUpdate(&oldController.ObjectMeta, &controller.ObjectMeta).Prefix("metadata")...) allErrs = append(allErrs, ValidateReplicationControllerSpec(&controller.Spec).Prefix("spec")...) - allErrs = append(allErrs, ValidateLabels(controller.Labels, "labels")...) + return allErrs } @@ -540,6 +607,7 @@ func ValidateReplicationControllerSpec(spec *api.ReplicationControllerSpec) errs if !selector.Matches(labels) { allErrs = append(allErrs, errs.NewFieldInvalid("template.labels", spec.Template.Labels, "selector does not match template")) } + allErrs = append(allErrs, ValidateLabels(spec.Template.Annotations, "annotations")...) allErrs = append(allErrs, ValidatePodTemplateSpec(spec.Template).Prefix("template")...) // RestartPolicy has already been first-order validated as per ValidatePodTemplateSpec(). if spec.Template.Spec.RestartPolicy.Always == nil { @@ -555,6 +623,7 @@ func ValidateReplicationControllerSpec(spec *api.ReplicationControllerSpec) errs func ValidatePodTemplateSpec(spec *api.PodTemplateSpec) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} allErrs = append(allErrs, ValidateLabels(spec.Labels, "labels")...) + allErrs = append(allErrs, ValidateLabels(spec.Annotations, "annotations")...) allErrs = append(allErrs, ValidatePodSpec(&spec.Spec).Prefix("spec")...) allErrs = append(allErrs, ValidateReadOnlyPersistentDisks(spec.Spec.Volumes).Prefix("spec.volumes")...) return allErrs @@ -573,12 +642,15 @@ func ValidateReadOnlyPersistentDisks(volumes []api.Volume) errs.ValidationErrorL } // ValidateBoundPod tests if required fields on a bound pod are set. +// TODO: to be removed. func ValidateBoundPod(pod *api.BoundPod) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} if len(pod.Name) == 0 { allErrs = append(allErrs, errs.NewFieldRequired("name", pod.Name)) - } else if !util.IsDNSSubdomain(pod.Name) { - allErrs = append(allErrs, errs.NewFieldInvalid("name", pod.Name, "")) + } else { + if ok, qualifier := nameIsDNSSubdomain(pod.Name); !ok { + allErrs = append(allErrs, errs.NewFieldInvalid("name", pod.Name, qualifier)) + } } if len(pod.Namespace) == 0 { allErrs = append(allErrs, errs.NewFieldRequired("namespace", pod.Namespace)) @@ -589,29 +661,28 @@ func ValidateBoundPod(pod *api.BoundPod) errs.ValidationErrorList { return allErrs } -// ValidateMinion tests if required fields in the minion are set. -func ValidateMinion(minion *api.Node) errs.ValidationErrorList { +// ValidateMinion tests if required fields in the node are set. +func ValidateMinion(node *api.Node) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} - if len(minion.Namespace) != 0 { - allErrs = append(allErrs, errs.NewFieldInvalid("namespace", minion.Namespace, "")) - } - if len(minion.Name) == 0 { - allErrs = append(allErrs, errs.NewFieldRequired("name", minion.Name)) - } - allErrs = append(allErrs, ValidateLabels(minion.Labels, "labels")...) + allErrs = append(allErrs, ValidateObjectMeta(&node.ObjectMeta, false, nameIsDNSSubdomain).Prefix("metadata")...) return allErrs } // ValidateMinionUpdate tests to make sure a minion update can be applied. Modifies oldMinion. func ValidateMinionUpdate(oldMinion *api.Node, minion *api.Node) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} - - if !api.Semantic.DeepEqual(minion.Status, api.NodeStatus{}) { - allErrs = append(allErrs, errs.NewFieldInvalid("status", minion.Status, "status must be empty")) - } - - // Allow users to update labels and capacity - oldMinion.Labels = minion.Labels + allErrs = append(allErrs, ValidateObjectMetaUpdate(&oldMinion.ObjectMeta, &minion.ObjectMeta).Prefix("metadata")...) + + // TODO: Enable the code once we have better api object.status update model. Currently, + // anyone can update node status. + // if !api.Semantic.DeepEqual(minion.Status, api.NodeStatus{}) { + // allErrs = append(allErrs, errs.NewFieldInvalid("status", minion.Status, "status must be empty")) + // } + + // TODO: move reset function to its own location + // Ignore metadata changes now that they have been tested + oldMinion.ObjectMeta = minion.ObjectMeta + // Allow users to update capacity oldMinion.Spec.Capacity = minion.Spec.Capacity // Clear status oldMinion.Status = minion.Status @@ -620,5 +691,85 @@ func ValidateMinionUpdate(oldMinion *api.Node, minion *api.Node) errs.Validation glog.V(4).Infof("Update failed validation %#v vs %#v", oldMinion, minion) allErrs = append(allErrs, fmt.Errorf("update contains more than labels or capacity changes")) } + + // TODO: validate Spec.Capacity + return allErrs +} + +// Typename is a generic representation for all compute resource typenames. +// Refer to docs/resources.md for more details. +func ValidateResourceName(str string) errs.ValidationErrorList { + if !util.IsQualifiedName(str) { + return errs.ValidationErrorList{fmt.Errorf("invalid compute resource typename format %q", str)} + } + + parts := strings.Split(str, "/") + switch len(parts) { + case 1: + if !api.IsStandardResourceName(parts[0]) { + return errs.ValidationErrorList{fmt.Errorf("invalid compute resource typename. %q is neither a standard resource type nor is fully qualified", str)} + } + break + case 2: + if parts[0] == api.DefaultResourceNamespace { + if !api.IsStandardResourceName(parts[1]) { + return errs.ValidationErrorList{fmt.Errorf("invalid compute resource typename. %q contains a compute resource type not supported", str)} + + } + } + break + } + + return errs.ValidationErrorList{} +} + +// ValidateLimitRange tests if required fields in the LimitRange are set. +func ValidateLimitRange(limitRange *api.LimitRange) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + if len(limitRange.Name) == 0 { + allErrs = append(allErrs, errs.NewFieldRequired("name", limitRange.Name)) + } else if !util.IsDNSSubdomain(limitRange.Name) { + allErrs = append(allErrs, errs.NewFieldInvalid("name", limitRange.Name, "")) + } + if len(limitRange.Namespace) == 0 { + allErrs = append(allErrs, errs.NewFieldRequired("namespace", limitRange.Namespace)) + } else if !util.IsDNSSubdomain(limitRange.Namespace) { + allErrs = append(allErrs, errs.NewFieldInvalid("namespace", limitRange.Namespace, "")) + } + // ensure resource names are properly qualified per docs/resources.md + for i := range limitRange.Spec.Limits { + limit := limitRange.Spec.Limits[i] + for k := range limit.Max { + allErrs = append(allErrs, ValidateResourceName(string(k))...) + } + for k := range limit.Min { + allErrs = append(allErrs, ValidateResourceName(string(k))...) + } + } + return allErrs +} + +// ValidateResourceQuota tests if required fields in the ResourceQuota are set. +func ValidateResourceQuota(resourceQuota *api.ResourceQuota) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + if len(resourceQuota.Name) == 0 { + allErrs = append(allErrs, errs.NewFieldRequired("name", resourceQuota.Name)) + } else if !util.IsDNSSubdomain(resourceQuota.Name) { + allErrs = append(allErrs, errs.NewFieldInvalid("name", resourceQuota.Name, "")) + } + if len(resourceQuota.Namespace) == 0 { + allErrs = append(allErrs, errs.NewFieldRequired("namespace", resourceQuota.Namespace)) + } else if !util.IsDNSSubdomain(resourceQuota.Namespace) { + allErrs = append(allErrs, errs.NewFieldInvalid("namespace", resourceQuota.Namespace, "")) + } + for k := range resourceQuota.Spec.Hard { + allErrs = append(allErrs, ValidateResourceName(string(k))...) + } + for k := range resourceQuota.Status.Hard { + allErrs = append(allErrs, ValidateResourceName(string(k))...) + } + for k := range resourceQuota.Status.Used { + allErrs = append(allErrs, ValidateResourceName(string(k))...) + } return allErrs } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation/validation_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation/validation_test.go index 1e0975ab2631..d91db387e924 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation/validation_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation/validation_test.go @@ -567,6 +567,24 @@ func TestValidatePod(t *testing.T) { Containers: []api.Container{{}}, }, }, + "bad label": { + ObjectMeta: api.ObjectMeta{ + Name: "abc", + Namespace: "ns", + Labels: map[string]string{ + "NoUppercaseOrSpecialCharsLike=Equals": "bar", + }, + }, + }, + "bad annotation": { + ObjectMeta: api.ObjectMeta{ + Name: "abc", + Namespace: "ns", + Annotations: map[string]string{ + "NoUppercaseOrSpecialCharsLike=Equals": "bar", + }, + }, + }, } for k, v := range errorCases { if errs := ValidatePod(&v); len(errs) == 0 { @@ -613,6 +631,26 @@ func TestValidatePodUpdate(t *testing.T) { true, "labels", }, + { + api.Pod{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Annotations: map[string]string{ + "foo": "bar", + }, + }, + }, + api.Pod{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Annotations: map[string]string{ + "bar": "foo", + }, + }, + }, + true, + "annotations", + }, { api.Pod{ ObjectMeta: api.ObjectMeta{ @@ -915,7 +953,7 @@ func TestValidateService(t *testing.T) { numErrs: 0, }, { - name: "invalid port in use", + name: "external port in use", svc: api.Service{ ObjectMeta: api.ObjectMeta{Name: "abc123", Namespace: api.NamespaceDefault}, Spec: api.ServiceSpec{ @@ -932,7 +970,7 @@ func TestValidateService(t *testing.T) { }, }, }, - numErrs: 1, + numErrs: 0, }, { name: "same port in use, but not external", @@ -1008,6 +1046,22 @@ func TestValidateService(t *testing.T) { }, numErrs: 1, }, + { + name: "invalid annotation", + svc: api.Service{ + ObjectMeta: api.ObjectMeta{ + Name: "abc123", + Namespace: api.NamespaceDefault, + Annotations: map[string]string{ + "NoUppercaseOrSpecialCharsLike=Equals": "bar", + }, + }, + Spec: api.ServiceSpec{ + Port: 8675, + }, + }, + numErrs: 1, + }, { name: "invalid selector", svc: api.Service{ @@ -1027,7 +1081,7 @@ func TestValidateService(t *testing.T) { for _, tc := range testCases { registry := registrytest.NewServiceRegistry() registry.List = tc.existing - errs := ValidateService(&tc.svc, registry, api.NewDefaultContext()) + errs := ValidateService(&tc.svc) if len(errs) != tc.numErrs { t.Errorf("Unexpected error list for case %q: %v", tc.name, utilerrors.NewAggregate(errs)) } @@ -1040,7 +1094,7 @@ func TestValidateService(t *testing.T) { Selector: map[string]string{"foo": "bar"}, }, } - errs := ValidateService(&svc, registrytest.NewServiceRegistry(), api.NewDefaultContext()) + errs := ValidateService(&svc) if len(errs) != 0 { t.Errorf("Unexpected non-zero error list: %#v", errs) } @@ -1173,6 +1227,19 @@ func TestValidateReplicationController(t *testing.T) { Template: &invalidPodTemplate.Spec, }, }, + "invalid_annotation": { + ObjectMeta: api.ObjectMeta{ + Name: "abc-123", + Namespace: api.NamespaceDefault, + Annotations: map[string]string{ + "NoUppercaseOrSpecialCharsLike=Equals": "bar", + }, + }, + Spec: api.ReplicationControllerSpec{ + Selector: validSelector, + Template: &validPodTemplate.Spec, + }, + }, "invalid restart policy 1": { ObjectMeta: api.ObjectMeta{ Name: "abc-123", @@ -1220,14 +1287,15 @@ func TestValidateReplicationController(t *testing.T) { for i := range errs { field := errs[i].(*errors.ValidationError).Field if !strings.HasPrefix(field, "spec.template.") && - field != "name" && - field != "namespace" && + field != "metadata.name" && + field != "metadata.namespace" && field != "spec.selector" && field != "spec.template" && field != "GCEPersistentDisk.ReadOnly" && field != "spec.replicas" && field != "spec.template.labels" && - field != "labels" { + field != "metadata.annotations" && + field != "metadata.labels" { t.Errorf("%s: missing prefix for: %v", k, errs[i]) } } @@ -1294,6 +1362,12 @@ func TestValidateMinion(t *testing.T) { Labels: invalidSelector, }, }, + "invalid-annotations": { + ObjectMeta: api.ObjectMeta{ + Name: "abc-123", + Annotations: invalidSelector, + }, + }, } for k, v := range errorCases { errs := ValidateMinion(&v) @@ -1302,8 +1376,10 @@ func TestValidateMinion(t *testing.T) { } for i := range errs { field := errs[i].(*errors.ValidationError).Field - if field != "name" && - field != "labels" { + if field != "metadata.name" && + field != "metadata.labels" && + field != "metadata.annotations" && + field != "metadata.namespace" { t.Errorf("%s: missing prefix for: %v", k, errs[i]) } } @@ -1400,20 +1476,6 @@ func TestValidateMinionUpdate(t *testing.T) { }, }, }, true}, - {api.Node{ - ObjectMeta: api.ObjectMeta{ - Name: "foo", - Labels: map[string]string{"bar": "foo"}, - }, - }, api.Node{ - ObjectMeta: api.ObjectMeta{ - Name: "foo", - Labels: map[string]string{"bar": "fooobaz"}, - }, - Status: api.NodeStatus{ - HostIP: "1.2.3.4", - }, - }, false}, {api.Node{ ObjectMeta: api.ObjectMeta{ Name: "foo", @@ -1429,14 +1491,372 @@ func TestValidateMinionUpdate(t *testing.T) { }, }, true}, } - for _, test := range tests { + for i, test := range tests { errs := ValidateMinionUpdate(&test.oldMinion, &test.minion) if test.valid && len(errs) > 0 { - t.Errorf("Unexpected error: %v", errs) + t.Errorf("%d: Unexpected error: %v", i, errs) t.Logf("%#v vs %#v", test.oldMinion.ObjectMeta, test.minion.ObjectMeta) } if !test.valid && len(errs) == 0 { - t.Errorf("Unexpected non-error") + t.Errorf("%d: Unexpected non-error", i) + } + } +} + +func TestValidateServiceUpdate(t *testing.T) { + tests := []struct { + oldService api.Service + service api.Service + valid bool + }{ + { // 0 + api.Service{}, + api.Service{}, + true}, + { // 1 + api.Service{ + ObjectMeta: api.ObjectMeta{ + Name: "foo"}}, + api.Service{ + ObjectMeta: api.ObjectMeta{ + Name: "bar"}, + }, false}, + { // 2 + api.Service{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{"foo": "bar"}, + }, + }, + api.Service{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{"foo": "baz"}, + }, + }, true}, + { // 3 + api.Service{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + }, + }, + api.Service{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{"foo": "baz"}, + }, + }, true}, + { // 4 + api.Service{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{"bar": "foo"}, + }, + }, + api.Service{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{"foo": "baz"}, + }, + }, true}, + { // 5 + api.Service{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Annotations: map[string]string{"bar": "foo"}, + }, + }, + api.Service{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Annotations: map[string]string{"foo": "baz"}, + }, + }, true}, + { // 6 + api.Service{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + }, + Spec: api.ServiceSpec{ + Selector: map[string]string{"foo": "baz"}, + }, + }, + api.Service{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + }, + Spec: api.ServiceSpec{ + Selector: map[string]string{"foo": "baz"}, + }, + }, true}, + { // 7 + api.Service{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{"bar": "foo"}, + }, + Spec: api.ServiceSpec{ + PortalIP: "127.0.0.1", + }, + }, + api.Service{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{"bar": "fooobaz"}, + }, + Spec: api.ServiceSpec{ + PortalIP: "new", + }, + }, false}, + { // 8 + api.Service{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{"bar": "foo"}, + }, + Spec: api.ServiceSpec{ + PortalIP: "127.0.0.1", + }, + }, + api.Service{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{"bar": "fooobaz"}, + }, + Spec: api.ServiceSpec{ + PortalIP: "", + }, + }, false}, + { // 9 + api.Service{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{"bar": "foo"}, + }, + Spec: api.ServiceSpec{ + PortalIP: "127.0.0.1", + }, + }, + api.Service{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{"bar": "fooobaz"}, + }, + Spec: api.ServiceSpec{ + PortalIP: "127.0.0.2", + }, + }, false}, + } + for i, test := range tests { + errs := ValidateServiceUpdate(&test.oldService, &test.service) + if test.valid && len(errs) > 0 { + t.Errorf("%d: Unexpected error: %v", i, errs) + t.Logf("%#v vs %#v", test.oldService.ObjectMeta, test.service.ObjectMeta) + } + if !test.valid && len(errs) == 0 { + t.Errorf("%d: Unexpected non-error", i) + } + } +} + +func TestValidateResourceNames(t *testing.T) { + longString := "a" + for i := 0; i < 6; i++ { + longString += longString + } + table := []struct { + input string + success bool + }{ + {"memory", true}, + {"cpu", true}, + {"network", false}, + {"disk", false}, + {"", false}, + {".", false}, + {"..", false}, + {"kubernetes.io/cpu", true}, + {"kubernetes.io/disk", false}, + {"my.favorite.app.co/12345", true}, + {"my.favorite.app.co/_12345", false}, + {"my.favorite.app.co/12345_", false}, + {"kubernetes.io/..", false}, + {"kubernetes.io/" + longString, false}, + {"kubernetes.io//", false}, + {"kubernetes.io", false}, + {"kubernetes.io/will/not/work/", false}, + } + for _, item := range table { + err := ValidateResourceName(item.input) + if len(err) != 0 && item.success { + t.Errorf("expected no failure for input %q", item.input) + } else if len(err) == 0 && !item.success { + t.Errorf("expected failure for input %q", item.input) + } + } +} + +func TestValidateLimitRange(t *testing.T) { + successCases := []api.LimitRange{ + { + ObjectMeta: api.ObjectMeta{ + Name: "abc", + Namespace: "foo", + }, + Spec: api.LimitRangeSpec{ + Limits: []api.LimitRangeItem{ + { + Type: api.LimitTypePod, + Max: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100"), + api.ResourceMemory: resource.MustParse("10000"), + }, + Min: api.ResourceList{ + api.ResourceCPU: resource.MustParse("0"), + api.ResourceMemory: resource.MustParse("100"), + }, + }, + }, + }, + }, + } + + for _, successCase := range successCases { + if errs := ValidateLimitRange(&successCase); len(errs) != 0 { + t.Errorf("expected success: %v", errs) + } + } + + errorCases := map[string]api.LimitRange{ + "zero-length Name": { + ObjectMeta: api.ObjectMeta{ + Name: "", + Namespace: "foo", + }, + Spec: api.LimitRangeSpec{ + Limits: []api.LimitRangeItem{ + { + Type: api.LimitTypePod, + Max: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100"), + api.ResourceMemory: resource.MustParse("10000"), + }, + Min: api.ResourceList{ + api.ResourceCPU: resource.MustParse("0"), + api.ResourceMemory: resource.MustParse("100"), + }, + }, + }, + }, + }, + "zero-length-namespace": { + ObjectMeta: api.ObjectMeta{ + Name: "abc", + Namespace: "", + }, + Spec: api.LimitRangeSpec{ + Limits: []api.LimitRangeItem{ + { + Type: api.LimitTypePod, + Max: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100"), + api.ResourceMemory: resource.MustParse("10000"), + }, + Min: api.ResourceList{ + api.ResourceCPU: resource.MustParse("0"), + api.ResourceMemory: resource.MustParse("100"), + }, + }, + }, + }, + }, + } + for k, v := range errorCases { + errs := ValidateLimitRange(&v) + if len(errs) == 0 { + t.Errorf("expected failure for %s", k) + } + for i := range errs { + field := errs[i].(*errors.ValidationError).Field + if field != "name" && + field != "namespace" { + t.Errorf("%s: missing prefix for: %v", k, errs[i]) + } + } + } +} + +func TestValidateResourceQuota(t *testing.T) { + successCases := []api.ResourceQuota{ + { + ObjectMeta: api.ObjectMeta{ + Name: "abc", + Namespace: "foo", + }, + Spec: api.ResourceQuotaSpec{ + Hard: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100"), + api.ResourceMemory: resource.MustParse("10000"), + api.ResourcePods: resource.MustParse("10"), + api.ResourceServices: resource.MustParse("10"), + api.ResourceReplicationControllers: resource.MustParse("10"), + api.ResourceQuotas: resource.MustParse("10"), + }, + }, + }, + } + + for _, successCase := range successCases { + if errs := ValidateResourceQuota(&successCase); len(errs) != 0 { + t.Errorf("expected success: %v", errs) + } + } + + errorCases := map[string]api.ResourceQuota{ + "zero-length Name": { + ObjectMeta: api.ObjectMeta{ + Name: "", + Namespace: "foo", + }, + Spec: api.ResourceQuotaSpec{ + Hard: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100"), + api.ResourceMemory: resource.MustParse("10000"), + api.ResourcePods: resource.MustParse("10"), + api.ResourceServices: resource.MustParse("10"), + api.ResourceReplicationControllers: resource.MustParse("10"), + api.ResourceQuotas: resource.MustParse("10"), + }, + }, + }, + "zero-length-namespace": { + ObjectMeta: api.ObjectMeta{ + Name: "abc", + Namespace: "", + }, + Spec: api.ResourceQuotaSpec{ + Hard: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100"), + api.ResourceMemory: resource.MustParse("10000"), + api.ResourcePods: resource.MustParse("10"), + api.ResourceServices: resource.MustParse("10"), + api.ResourceReplicationControllers: resource.MustParse("10"), + api.ResourceQuotas: resource.MustParse("10"), + }, + }, + }, + } + for k, v := range errorCases { + errs := ValidateResourceQuota(&v) + if len(errs) == 0 { + t.Errorf("expected failure for %s", k) + } + for i := range errs { + field := errs[i].(*errors.ValidationError).Field + if field != "name" && + field != "namespace" { + t.Errorf("%s: missing prefix for: %v", k, errs[i]) + } } } } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/apiserver.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/apiserver.go index 70eec069e378..54aad06a9e20 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/apiserver.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/apiserver.go @@ -31,6 +31,8 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/healthz" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/version" "github.com/emicklei/go-restful" @@ -49,10 +51,6 @@ type defaultAPIServer struct { group *APIGroupVersion } -const ( - StatusUnprocessableEntity = 422 -) - // Handle returns a Handler function that exposes the provided storage interfaces // as RESTful resources at prefix, serialized by codec, and also includes the support // http resources. @@ -93,8 +91,6 @@ func NewAPIGroupVersion(storage map[string]RESTStorage, codec runtime.Codec, can selfLinker: selfLinker, ops: NewOperations(), admissionControl: admissionControl, - // Delay just long enough to handle most simple write operations - asyncOpWait: time.Millisecond * 25, }} } @@ -128,8 +124,7 @@ func registerResourceHandlers(ws *restful.WebService, version string, path strin createRoute := ws.POST(path).To(h). Doc("create a " + kind). - Operation("create" + kind). - Reads(versionedObject) // from the request + Operation("create" + kind) addParamIf(createRoute, namespaceParam, namespaceScope) if _, ok := storage.(RESTCreater); ok { ws.Route(createRoute.Reads(versionedObject)) // from the request @@ -200,7 +195,7 @@ func addParamIf(b *restful.RouteBuilder, parameter *restful.Parameter, shouldAdd return b.Param(parameter) } -// InstallREST registers the REST handlers (storage, watch, and operations) into a restful Container. +// InstallREST registers the REST handlers (storage, watch, proxy and redirect) into a restful Container. // It is expected that the provided path root prefix will serve all operations. Root MUST NOT end // in a slash. A restful WebService is created for the group and version. func (g *APIGroupVersion) InstallREST(container *restful.Container, mux Mux, root string, version string) error { @@ -215,7 +210,6 @@ func (g *APIGroupVersion) InstallREST(container *restful.Container, mux Mux, roo } proxyHandler := &ProxyHandler{prefix + "/proxy/", g.handler.storage, g.handler.codec} redirectHandler := &RedirectHandler{g.handler.storage, g.handler.codec} - opHandler := &OperationHandler{g.handler.ops, g.handler.codec} // Create a new WebService for this APIGroupVersion at the specified path prefix // TODO: Pass in more descriptive documentation @@ -255,14 +249,16 @@ func (g *APIGroupVersion) InstallREST(container *restful.Container, mux Mux, roo strippedHandler.ServeHTTP(resp.ResponseWriter, req.Request) } + registrationErrors := make([]error, 0) + for path, storage := range g.handler.storage { // register legacy patterns where namespace is optional in path if err := registerResourceHandlers(ws, version, path, storage, h, false); err != nil { - return err + registrationErrors = append(registrationErrors, err) } // register pattern where namespace is required in path if err := registerResourceHandlers(ws, version, path, storage, h, true); err != nil { - return err + registrationErrors = append(registrationErrors, err) } } @@ -272,12 +268,10 @@ func (g *APIGroupVersion) InstallREST(container *restful.Container, mux Mux, roo mux.Handle(prefix+"/watch/", http.StripPrefix(prefix+"/watch/", watchHandler)) mux.Handle(prefix+"/proxy/", http.StripPrefix(prefix+"/proxy/", proxyHandler)) mux.Handle(prefix+"/redirect/", http.StripPrefix(prefix+"/redirect/", redirectHandler)) - mux.Handle(prefix+"/operations", http.StripPrefix(prefix+"/operations", opHandler)) - mux.Handle(prefix+"/operations/", http.StripPrefix(prefix+"/operations/", opHandler)) container.Add(ws) - return nil + return errors.NewAggregate(registrationErrors) } // TODO: Convert to go-restful @@ -373,6 +367,7 @@ func errorJSON(err error, codec runtime.Codec, w http.ResponseWriter) { // errorJSONFatal renders an error to the response, and if codec fails will render plaintext func errorJSONFatal(err error, codec runtime.Codec, w http.ResponseWriter) { + util.HandleError(fmt.Errorf("apiserver was unable to write a JSON response: %v", err)) status := errToAPIStatus(err) output, err := codec.Encode(status) if err != nil { @@ -387,7 +382,6 @@ func errorJSONFatal(err error, codec runtime.Codec, w http.ResponseWriter) { // writeRawJSON writes a non-API object in JSON. func writeRawJSON(statusCode int, object interface{}, w http.ResponseWriter) { - // PR #2243: Pretty-print JSON by default. output, err := json.MarshalIndent(object, "", " ") if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/apiserver_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/apiserver_test.go index 81b4193c96f4..50840d1aba4e 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/apiserver_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/apiserver_test.go @@ -74,15 +74,14 @@ func interfacesFor(version string) (*meta.VersionInterfaces, error) { func init() { // Certain API objects are returned regardless of the contents of storage: // api.Status is returned in errors - // api.Operation/api.OperationList are returned by /operations // "internal" version api.Scheme.AddKnownTypes("", &Simple{}, &SimpleList{}, - &api.Status{}, &api.Operation{}, &api.OperationList{}) + &api.Status{}) // "version" version // TODO: Use versioned api objects? api.Scheme.AddKnownTypes(testVersion, &Simple{}, &SimpleList{}, - &api.Status{}, &api.Operation{}, &api.OperationList{}) + &api.Status{}) defMapper := meta.NewDefaultRESTMapper( versions, @@ -689,88 +688,6 @@ func TestUpdateMissing(t *testing.T) { } } -func TestCreate(t *testing.T) { - wait := sync.WaitGroup{} - wait.Add(1) - simpleStorage := &SimpleRESTStorage{ - injectedFunction: func(obj runtime.Object) (returnObj runtime.Object, err error) { - wait.Wait() - return &Simple{}, nil - }, - } - handler := Handle(map[string]RESTStorage{ - "foo": simpleStorage, - }, codec, "/prefix", testVersion, selfLinker, admissionControl) - handler.(*defaultAPIServer).group.handler.asyncOpWait = 0 - server := httptest.NewServer(handler) - defer server.Close() - client := http.Client{} - - simple := &Simple{ - Other: "foo", - } - data, _ := codec.Encode(simple) - request, err := http.NewRequest("POST", server.URL+"/prefix/version/foo", bytes.NewBuffer(data)) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - - response, err := client.Do(request) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - - if response.StatusCode != http.StatusAccepted { - t.Errorf("Unexpected response %#v", response) - } - - var itemOut api.Status - body, err := extractBody(response, &itemOut) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - - if itemOut.Status != api.StatusWorking || itemOut.Details == nil || itemOut.Details.ID == "" { - t.Errorf("Unexpected status: %#v (%s)", itemOut, string(body)) - } - wait.Done() -} - -func TestCreateInvokesAdmissionControl(t *testing.T) { - wait := sync.WaitGroup{} - wait.Add(1) - simpleStorage := &SimpleRESTStorage{ - injectedFunction: func(obj runtime.Object) (returnObj runtime.Object, err error) { - wait.Wait() - return &Simple{}, nil - }, - } - handler := Handle(map[string]RESTStorage{ - "foo": simpleStorage, - }, codec, "/prefix", testVersion, selfLinker, deny.NewAlwaysDeny()) - handler.(*defaultAPIServer).group.handler.asyncOpWait = 0 - server := httptest.NewServer(handler) - defer server.Close() - client := http.Client{} - - simple := &Simple{ - Other: "foo", - } - data, _ := codec.Encode(simple) - request, err := http.NewRequest("POST", server.URL+"/prefix/version/foo", bytes.NewBuffer(data)) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - - response, err := client.Do(request) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - if response.StatusCode != http.StatusForbidden { - t.Errorf("Unexpected response %#v", response) - } -} - func TestCreateNotFound(t *testing.T) { handler := Handle(map[string]RESTStorage{ "simple": &SimpleRESTStorage{ @@ -831,7 +748,7 @@ func (s *setTestSelfLinker) SetSelfLink(obj runtime.Object, selfLink string) err return nil } -func TestSyncCreate(t *testing.T) { +func TestCreate(t *testing.T) { storage := SimpleRESTStorage{ injectedFunction: func(obj runtime.Object) (runtime.Object, error) { time.Sleep(5 * time.Millisecond) @@ -855,7 +772,7 @@ func TestSyncCreate(t *testing.T) { Other: "bar", } data, _ := codec.Encode(simple) - request, err := http.NewRequest("POST", server.URL+"/prefix/version/ns/other/foo?sync=true", bytes.NewBuffer(data)) + request, err := http.NewRequest("POST", server.URL+"/prefix/version/ns/other/foo", bytes.NewBuffer(data)) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -889,6 +806,51 @@ func TestSyncCreate(t *testing.T) { } } +func TestCreateInvokesAdmissionControl(t *testing.T) { + storage := SimpleRESTStorage{ + injectedFunction: func(obj runtime.Object) (runtime.Object, error) { + time.Sleep(5 * time.Millisecond) + return obj, nil + }, + } + selfLinker := &setTestSelfLinker{ + t: t, + name: "bar", + namespace: "other", + expectedSet: "/prefix/version/ns/other/foo/bar", + } + handler := Handle(map[string]RESTStorage{ + "foo": &storage, + }, codec, "/prefix", testVersion, selfLinker, deny.NewAlwaysDeny()) + server := httptest.NewServer(handler) + defer server.Close() + client := http.Client{} + + simple := &Simple{ + Other: "bar", + } + data, _ := codec.Encode(simple) + request, err := http.NewRequest("POST", server.URL+"/prefix/version/ns/other/foo", bytes.NewBuffer(data)) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + + wg := sync.WaitGroup{} + wg.Add(1) + var response *http.Response + go func() { + response, err = client.Do(request) + wg.Done() + }() + wg.Wait() + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if response.StatusCode != http.StatusForbidden { + t.Errorf("Unexpected status: %d, Expected: %d, %#v", response.StatusCode, http.StatusForbidden, response) + } +} + func expectApiStatus(t *testing.T, method, url string, data []byte, code int) *api.Status { client := http.Client{} request, err := http.NewRequest(method, url, bytes.NewBuffer(data)) @@ -913,14 +875,13 @@ func expectApiStatus(t *testing.T, method, url string, data []byte, code int) *a return &status } -func TestAsyncDelayReturnsError(t *testing.T) { +func TestDelayReturnsError(t *testing.T) { storage := SimpleRESTStorage{ injectedFunction: func(obj runtime.Object) (runtime.Object, error) { return nil, apierrs.NewAlreadyExists("foo", "bar") }, } handler := Handle(map[string]RESTStorage{"foo": &storage}, codec, "/prefix", testVersion, selfLinker, admissionControl) - handler.(*defaultAPIServer).group.handler.asyncOpWait = time.Millisecond / 2 server := httptest.NewServer(handler) defer server.Close() @@ -930,63 +891,6 @@ func TestAsyncDelayReturnsError(t *testing.T) { } } -func TestAsyncCreateError(t *testing.T) { - ch := make(chan struct{}) - storage := SimpleRESTStorage{ - injectedFunction: func(obj runtime.Object) (runtime.Object, error) { - <-ch - return nil, apierrs.NewAlreadyExists("foo", "bar") - }, - } - selfLinker := &setTestSelfLinker{ - t: t, - name: "bar", - expectedSet: "/prefix/version/foo/bar", - } - handler := Handle(map[string]RESTStorage{"foo": &storage}, codec, "/prefix", testVersion, selfLinker, admissionControl) - handler.(*defaultAPIServer).group.handler.asyncOpWait = 0 - server := httptest.NewServer(handler) - defer server.Close() - - simple := &Simple{Other: "bar"} - data, _ := codec.Encode(simple) - - status := expectApiStatus(t, "POST", fmt.Sprintf("%s/prefix/version/foo", server.URL), data, http.StatusAccepted) - if status.Status != api.StatusWorking || status.Details == nil || status.Details.ID == "" { - t.Errorf("Unexpected status %#v", status) - } - - otherStatus := expectApiStatus(t, "GET", fmt.Sprintf("%s/prefix/version/operations/%s", server.URL, status.Details.ID), []byte{}, http.StatusAccepted) - if !reflect.DeepEqual(status, otherStatus) { - t.Errorf("Expected %#v, Got %#v", status, otherStatus) - } - - ch <- struct{}{} - time.Sleep(time.Millisecond) - - finalStatus := expectApiStatus(t, "GET", fmt.Sprintf("%s/prefix/version/operations/%s?after=1", server.URL, status.Details.ID), []byte{}, http.StatusOK) - expectedErr := apierrs.NewAlreadyExists("foo", "bar") - expectedStatus := &api.Status{ - Status: api.StatusFailure, - Code: http.StatusConflict, - Reason: "AlreadyExists", - Message: expectedErr.Error(), - Details: &api.StatusDetails{ - Kind: "foo", - ID: "bar", - }, - } - if !reflect.DeepEqual(expectedStatus, finalStatus) { - t.Errorf("Expected %#v, Got %#v", expectedStatus, finalStatus) - if finalStatus.Details != nil { - t.Logf("Details %#v, Got %#v", *expectedStatus.Details, *finalStatus.Details) - } - } - if !selfLinker.called { - t.Errorf("Never set self link") - } -} - type UnregisteredAPIObject struct { Value string } @@ -1031,7 +935,7 @@ func TestWriteRAWJSONMarshalError(t *testing.T) { } } -func TestSyncCreateTimeout(t *testing.T) { +func TestCreateTimeout(t *testing.T) { testOver := make(chan struct{}) defer close(testOver) storage := SimpleRESTStorage{ @@ -1049,8 +953,8 @@ func TestSyncCreateTimeout(t *testing.T) { simple := &Simple{Other: "foo"} data, _ := codec.Encode(simple) - itemOut := expectApiStatus(t, "POST", server.URL+"/prefix/version/foo?sync=true&timeout=4ms", data, http.StatusAccepted) - if itemOut.Status != api.StatusWorking || itemOut.Details == nil || itemOut.Details.ID == "" { + itemOut := expectApiStatus(t, "POST", server.URL+"/prefix/version/foo?timeout=4ms", data, http.StatusAccepted) + if itemOut.Status != api.StatusFailure || itemOut.Reason != api.StatusReasonTimeout { t.Errorf("Unexpected status %#v", itemOut) } } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/handlers.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/handlers.go index e7374f18df0a..46eda63af0c2 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/handlers.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/handlers.go @@ -24,6 +24,7 @@ import ( "strings" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authorizer" authhandlers "github.com/GoogleCloudPlatform/kubernetes/pkg/auth/handlers" "github.com/GoogleCloudPlatform/kubernetes/pkg/httplog" @@ -71,8 +72,10 @@ func RateLimit(rl util.RateLimiter, handler http.Handler) http.Handler { handler.ServeHTTP(w, req) return } - w.WriteHeader(http.StatusServiceUnavailable) - fmt.Fprintf(w, "Rate limit exceeded.") + // Return a 429 status indicating "Too Many Requests" + w.Header().Set("Retry-After", "1") + w.WriteHeader(errors.StatusTooManyRequests) + fmt.Fprintf(w, "Rate limit is 10 QPS or a burst of 200") }) } @@ -95,7 +98,7 @@ func RecoverPanics(handler http.Handler) http.Handler { http.StatusTemporaryRedirect, http.StatusConflict, http.StatusNotFound, - StatusUnprocessableEntity, + errors.StatusUnprocessableEntity, ), ).Log() diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/operation.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/operation.go index 6d95d1d7261c..8d0734994721 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/operation.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/operation.go @@ -17,7 +17,6 @@ limitations under the License. package apiserver import ( - "net/http" "sort" "strconv" "sync" @@ -25,43 +24,9 @@ import ( "time" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" ) -type OperationHandler struct { - ops *Operations - codec runtime.Codec -} - -func (h *OperationHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { - parts := splitPath(req.URL.Path) - if len(parts) > 1 || req.Method != "GET" { - notFound(w, req) - return - } - if len(parts) == 0 { - // List outstanding operations. - list := h.ops.List() - writeJSON(http.StatusOK, h.codec, list, w) - return - } - - op := h.ops.Get(parts[0]) - if op == nil { - notFound(w, req) - return - } - - result, complete := op.StatusOrResult() - obj := result.Object - if complete { - writeJSON(http.StatusOK, h.codec, obj, w) - } else { - writeJSON(http.StatusAccepted, h.codec, obj, w) - } -} - // Operation represents an ongoing action which the server is performing. type Operation struct { ID string @@ -199,9 +164,8 @@ func (op *Operation) StatusOrResult() (description RESTResult, finished bool) { if op.finished == nil { return RESTResult{Object: &api.Status{ - Status: api.StatusWorking, - Reason: api.StatusReasonWorking, - Details: &api.StatusDetails{ID: op.ID, Kind: "operation"}, + Status: api.StatusFailure, + Reason: api.StatusReasonTimeout, }}, false } return op.result, true diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/operation_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/operation_test.go deleted file mode 100644 index 8b4f5f3ef668..000000000000 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/operation_test.go +++ /dev/null @@ -1,225 +0,0 @@ -/* -Copyright 2014 Google Inc. All rights reserved. - -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 apiserver - -import ( - "bytes" - "io/ioutil" - "net/http" - "net/http/httptest" - "sync/atomic" - "testing" - "time" - - // TODO: remove dependency on api, apiserver should be generic - "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - _ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1" - "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" -) - -func TestOperation(t *testing.T) { - ops := NewOperations() - - c := make(chan RESTResult) - called := make(chan struct{}) - op := ops.NewOperation(c, func(RESTResult) { go close(called) }) - // Allow context switch, so that op's ID can get added to the map and Get will work. - // This is just so we can test Get. Ordinary users have no need to call Get immediately - // after calling NewOperation, because it returns the operation directly. - time.Sleep(time.Millisecond) - go func() { - time.Sleep(500 * time.Millisecond) - c <- RESTResult{Object: &Simple{ObjectMeta: api.ObjectMeta{Name: "All done"}}} - }() - - if op.expired(time.Now().Add(-time.Minute)) { - t.Errorf("Expired before finished: %#v", op) - } - ops.expire(time.Minute) - if tmp := ops.Get(op.ID); tmp == nil { - t.Errorf("expire incorrectly removed the operation %#v", ops) - } - - op.WaitFor(10 * time.Millisecond) - if _, completed := op.StatusOrResult(); completed { - t.Errorf("Unexpectedly fast completion") - } - - const waiters = 10 - var waited int32 - for i := 0; i < waiters; i++ { - go func() { - op.WaitFor(time.Hour) - atomic.AddInt32(&waited, 1) - }() - } - - op.WaitFor(time.Minute) - if _, completed := op.StatusOrResult(); !completed { - t.Errorf("Unexpectedly slow completion") - } - - _, open := <-called - if open { - t.Errorf("expected hook to be called!") - } - - time.Sleep(100 * time.Millisecond) - finished := atomic.LoadInt32(&waited) - if finished != waiters { - t.Errorf("Multiple waiters doesn't work, only %v finished", finished) - } - - if op.expired(time.Now().Add(-time.Second)) { - t.Errorf("Should not be expired: %#v", op) - } - if !op.expired(time.Now().Add(-80 * time.Millisecond)) { - t.Errorf("Should be expired: %#v", op) - } - - ops.expire(80 * time.Millisecond) - if tmp := ops.Get(op.ID); tmp != nil { - t.Errorf("expire failed to remove the operation %#v", ops) - } - - if op.result.Object.(*Simple).Name != "All done" { - t.Errorf("Got unexpected result: %#v", op.result) - } -} - -func TestOperationsList(t *testing.T) { - testOver := make(chan struct{}) - defer close(testOver) - simpleStorage := &SimpleRESTStorage{ - injectedFunction: func(obj runtime.Object) (runtime.Object, error) { - // Eliminate flakes by ensuring the create operation takes longer than this test. - <-testOver - return obj, nil - }, - } - handler := Handle(map[string]RESTStorage{ - "foo": simpleStorage, - }, codec, "/prefix", "version", selfLinker, admissionControl) - handler.(*defaultAPIServer).group.handler.asyncOpWait = 0 - server := httptest.NewServer(handler) - defer server.Close() - client := http.Client{} - - simple := &Simple{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - } - data, err := codec.Encode(simple) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - response, err := client.Post(server.URL+"/prefix/version/foo", "application/json", bytes.NewBuffer(data)) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if response.StatusCode != http.StatusAccepted { - t.Fatalf("Unexpected response %#v", response) - } - - response, err = client.Get(server.URL + "/prefix/version/operations") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if response.StatusCode != http.StatusOK { - t.Fatalf("unexpected status code %#v", response) - } - body, err := ioutil.ReadAll(response.Body) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - obj, err := codec.Decode(body) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - oplist, ok := obj.(*api.OperationList) - if !ok { - t.Fatalf("expected ServerOpList, got %#v", obj) - } - if len(oplist.Items) != 1 { - t.Errorf("expected 1 operation, got %#v", obj) - } -} - -func TestOpGet(t *testing.T) { - testOver := make(chan struct{}) - defer close(testOver) - simpleStorage := &SimpleRESTStorage{ - injectedFunction: func(obj runtime.Object) (runtime.Object, error) { - // Eliminate flakes by ensuring the create operation takes longer than this test. - <-testOver - return obj, nil - }, - } - handler := Handle(map[string]RESTStorage{ - "foo": simpleStorage, - }, codec, "/prefix", "version", selfLinker, admissionControl) - handler.(*defaultAPIServer).group.handler.asyncOpWait = 0 - server := httptest.NewServer(handler) - defer server.Close() - client := http.Client{} - - simple := &Simple{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - } - data, err := codec.Encode(simple) - t.Log(string(data)) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - request, err := http.NewRequest("POST", server.URL+"/prefix/version/foo", bytes.NewBuffer(data)) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - response, err := client.Do(request) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - if response.StatusCode != http.StatusAccepted { - t.Fatalf("Unexpected response %#v", response) - } - - var itemOut api.Status - body, err := extractBody(response, &itemOut) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - if itemOut.Status != api.StatusWorking || itemOut.Details == nil || itemOut.Details.ID == "" { - t.Fatalf("Unexpected status: %#v (%s)", itemOut, string(body)) - } - - req2, err := http.NewRequest("GET", server.URL+"/prefix/version/operations/"+itemOut.Details.ID, nil) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - _, err = client.Do(req2) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - if response.StatusCode != http.StatusAccepted { - t.Errorf("Unexpected response %#v", response) - } -} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/resthandler.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/resthandler.go index 61a5447f9e89..cb34aa1e2330 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/resthandler.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/resthandler.go @@ -37,7 +37,6 @@ type RESTHandler struct { canonicalPrefix string selfLinker runtime.SelfLinker ops *Operations - asyncOpWait time.Duration admissionControl admission.Interface } @@ -144,12 +143,11 @@ func curry(f func(runtime.Object, *http.Request) error, req *http.Request) func( // DELETE /foo/bar delete 'bar' // Returns 404 if the method/pattern doesn't match one of these entries // The s accepts several query parameters: -// sync=[false|true] Synchronous request (only applies to create, update, delete operations) -// timeout= Timeout for synchronous requests, only applies if sync=true +// timeout= Timeout for synchronous requests // labels= Used for filtering list operations func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w http.ResponseWriter, storage RESTStorage, namespace, kind string) { ctx := api.WithNamespace(api.NewContext(), namespace) - sync := req.URL.Query().Get("sync") == "true" + // TODO: Document the timeout query parameter. timeout := parseTimeout(req.URL.Query().Get("timeout")) switch req.Method { case "GET": @@ -235,7 +233,7 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt errorJSON(err, h.codec, w) return } - op := h.createOperation(out, sync, timeout, curry(h.setSelfLinkAddName, req)) + op := h.createOperation(out, timeout, curry(h.setSelfLinkAddName, req)) h.finishReq(op, req, w) case "DELETE": @@ -261,7 +259,7 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt errorJSON(err, h.codec, w) return } - op := h.createOperation(out, sync, timeout, nil) + op := h.createOperation(out, timeout, nil) h.finishReq(op, req, w) case "PUT": @@ -299,7 +297,7 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt errorJSON(err, h.codec, w) return } - op := h.createOperation(out, sync, timeout, curry(h.setSelfLink, req)) + op := h.createOperation(out, timeout, curry(h.setSelfLink, req)) h.finishReq(op, req, w) default: @@ -308,13 +306,9 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt } // createOperation creates an operation to process a channel response. -func (h *RESTHandler) createOperation(out <-chan RESTResult, sync bool, timeout time.Duration, onReceive func(RESTResult)) *Operation { +func (h *RESTHandler) createOperation(out <-chan RESTResult, timeout time.Duration, onReceive func(RESTResult)) *Operation { op := h.ops.NewOperation(out, onReceive) - if sync { - op.WaitFor(timeout) - } else if h.asyncOpWait != 0 { - op.WaitFor(h.asyncOpWait) - } + op.WaitFor(timeout) return op } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/validator.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/validator.go index bd8bb1e21e65..e1c47803cb96 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/validator.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/validator.go @@ -24,7 +24,7 @@ import ( "net/http" "strconv" - "github.com/GoogleCloudPlatform/kubernetes/pkg/health" + "github.com/GoogleCloudPlatform/kubernetes/pkg/probe" ) // TODO: this basic interface is duplicated in N places. consolidate? @@ -45,29 +45,30 @@ type validator struct { client httpGet } -func (s *Server) check(client httpGet) (health.Status, string, error) { +// TODO: can this use pkg/probe/http +func (s *Server) check(client httpGet) (probe.Status, string, error) { resp, err := client.Get("http://" + net.JoinHostPort(s.Addr, strconv.Itoa(s.Port)) + s.Path) if err != nil { - return health.Unknown, "", err + return probe.Unknown, "", err } defer resp.Body.Close() data, err := ioutil.ReadAll(resp.Body) if err != nil { - return health.Unknown, string(data), err + return probe.Unknown, string(data), err } if resp.StatusCode != http.StatusOK { - return health.Unhealthy, string(data), + return probe.Failure, string(data), fmt.Errorf("unhealthy http status code: %d (%s)", resp.StatusCode, resp.Status) } - return health.Healthy, string(data), nil + return probe.Success, string(data), nil } type ServerStatus struct { - Component string `json:"component,omitempty"` - Health string `json:"health,omitempty"` - HealthCode health.Status `json:"healthCode,omitempty"` - Msg string `json:"msg,omitempty"` - Err string `json:"err,omitempty"` + Component string `json:"component,omitempty"` + Health string `json:"health,omitempty"` + HealthCode probe.Status `json:"healthCode,omitempty"` + Msg string `json:"msg,omitempty"` + Err string `json:"err,omitempty"` } func (v *validator) ServeHTTP(w http.ResponseWriter, r *http.Request) { diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/validator_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/validator_test.go index ee4d5f03b86d..0a9477135a29 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/validator_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver/validator_test.go @@ -25,7 +25,7 @@ import ( "net/http/httptest" "testing" - "github.com/GoogleCloudPlatform/kubernetes/pkg/health" + "github.com/GoogleCloudPlatform/kubernetes/pkg/probe" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" ) @@ -54,13 +54,13 @@ func TestValidate(t *testing.T) { tests := []struct { err error data string - expectedStatus health.Status + expectedStatus probe.Status code int expectErr bool }{ - {fmt.Errorf("test error"), "", health.Unknown, 500 /*ignored*/, true}, - {nil, "foo", health.Healthy, 200, false}, - {nil, "foo", health.Unhealthy, 500, true}, + {fmt.Errorf("test error"), "", probe.Unknown, 500 /*ignored*/, true}, + {nil, "foo", probe.Success, 200, false}, + {nil, "foo", probe.Failure, 500, true}, } s := Server{Addr: "foo.com", Port: 8080, Path: "/healthz"} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authorizer/abac/example_policy_file.jsonl b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authorizer/abac/example_policy_file.jsonl index 7842fa897494..ba566f16ea3a 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authorizer/abac/example_policy_file.jsonl +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/auth/authorizer/abac/example_policy_file.jsonl @@ -1,7 +1,9 @@ {"user":"admin"} {"user":"scheduler", "readonly": true, "kind": "pods"} {"user":"scheduler", "kind": "bindings"} -{"user":"kubelet", "readonly": true, "kind": "bindings"} +{"user":"kubelet", "readonly": true, "kind": "pods"} +{"user":"kubelet", "readonly": true, "kind": "services"} +{"user":"kubelet", "readonly": true, "kind": "endpoints"} {"user":"kubelet", "kind": "events"} {"user":"alice", "ns": "projectCaribou"} {"user":"bob", "readonly": true, "ns": "projectCaribou"} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/fifo.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/fifo.go index 831693599873..a27028f74262 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/fifo.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/fifo.go @@ -17,9 +17,8 @@ limitations under the License. package cache import ( + "fmt" "sync" - - "github.com/GoogleCloudPlatform/kubernetes/pkg/util" ) // FIFO receives adds and updates from a Reflector, and puts them in a queue for @@ -33,11 +32,18 @@ type FIFO struct { // We depend on the property that items in the set are in the queue and vice versa. items map[string]interface{} queue []string + // keyFunc is used to make the key used for queued item insertion and retrieval, and + // should be deterministic. + keyFunc KeyFunc } // Add inserts an item, and puts it in the queue. The item is only enqueued // if it doesn't already exist in the set. -func (f *FIFO) Add(id string, obj interface{}) { +func (f *FIFO) Add(obj interface{}) error { + id, err := f.keyFunc(obj) + if err != nil { + return fmt.Errorf("couldn't create key for object: %v", err) + } f.lock.Lock() defer f.lock.Unlock() if _, exists := f.items[id]; !exists { @@ -45,20 +51,26 @@ func (f *FIFO) Add(id string, obj interface{}) { } f.items[id] = obj f.cond.Broadcast() + return nil } // Update is the same as Add in this implementation. -func (f *FIFO) Update(id string, obj interface{}) { - f.Add(id, obj) +func (f *FIFO) Update(obj interface{}) error { + return f.Add(obj) } // Delete removes an item. It doesn't add it to the queue, because // this implementation assumes the consumer only cares about the objects, // not the order in which they were created/added. -func (f *FIFO) Delete(id string) { +func (f *FIFO) Delete(obj interface{}) error { + id, err := f.keyFunc(obj) + if err != nil { + return fmt.Errorf("couldn't create key for object: %v", err) + } f.lock.Lock() defer f.lock.Unlock() delete(f.items, id) + return err } // List returns a list of all the items. @@ -72,25 +84,16 @@ func (f *FIFO) List() []interface{} { return list } -// ContainedIDs returns a util.StringSet containing all IDs of the stored items. -// This is a snapshot of a moment in time, and one should keep in mind that -// other go routines can add or remove items after you call this. -func (c *FIFO) ContainedIDs() util.StringSet { - c.lock.RLock() - defer c.lock.RUnlock() - set := util.StringSet{} - for id := range c.items { - set.Insert(id) - } - return set -} - // Get returns the requested item, or sets exists=false. -func (f *FIFO) Get(id string) (item interface{}, exists bool) { +func (f *FIFO) Get(obj interface{}) (item interface{}, exists bool, err error) { + id, err := f.keyFunc(obj) + if err != nil { + return nil, false, fmt.Errorf("couldn't create key for object: %v", err) + } f.lock.RLock() defer f.lock.RUnlock() item, exists = f.items[id] - return item, exists + return item, exists, nil } // Pop waits until an item is ready and returns it. If multiple items are @@ -120,25 +123,36 @@ func (f *FIFO) Pop() interface{} { // 'f' takes ownersip of the map, you should not reference the map again // after calling this function. f's queue is reset, too; upon return, it // will contain the items in the map, in no particular order. -func (f *FIFO) Replace(idToObj map[string]interface{}) { +func (f *FIFO) Replace(list []interface{}) error { + items := map[string]interface{}{} + for _, item := range list { + key, err := f.keyFunc(item) + if err != nil { + return fmt.Errorf("couldn't create key for object: %v", err) + } + items[key] = item + } + f.lock.Lock() defer f.lock.Unlock() - f.items = idToObj + f.items = items f.queue = f.queue[:0] - for id := range idToObj { + for id := range items { f.queue = append(f.queue, id) } if len(f.queue) > 0 { f.cond.Broadcast() } + return nil } // NewFIFO returns a Store which can be used to queue up items to // process. -func NewFIFO() *FIFO { +func NewFIFO(keyFunc KeyFunc) *FIFO { f := &FIFO{ - items: map[string]interface{}{}, - queue: []string{}, + items: map[string]interface{}{}, + queue: []string{}, + keyFunc: keyFunc, } f.cond.L = &f.lock return f diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/fifo_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/fifo_test.go index 2b7106a5c46e..1ba6f07e0941 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/fifo_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/fifo_test.go @@ -21,30 +21,43 @@ import ( "time" ) +func testFifoObjectKeyFunc(obj interface{}) (string, error) { + return obj.(testFifoObject).name, nil +} + +type testFifoObject struct { + name string + val interface{} +} + func TestFIFO_basic(t *testing.T) { - f := NewFIFO() + mkObj := func(name string, val interface{}) testFifoObject { + return testFifoObject{name: name, val: val} + } + + f := NewFIFO(testFifoObjectKeyFunc) const amount = 500 go func() { for i := 0; i < amount; i++ { - f.Add(string([]rune{'a', rune(i)}), i+1) + f.Add(mkObj(string([]rune{'a', rune(i)}), i+1)) } }() go func() { - for u := uint(0); u < amount; u++ { - f.Add(string([]rune{'b', rune(u)}), u+1) + for u := uint64(0); u < amount; u++ { + f.Add(mkObj(string([]rune{'b', rune(u)}), u+1)) } }() lastInt := int(0) - lastUint := uint(0) + lastUint := uint64(0) for i := 0; i < amount*2; i++ { - switch obj := f.Pop().(type) { + switch obj := f.Pop().(testFifoObject).val.(type) { case int: if obj <= lastInt { t.Errorf("got %v (int) out of order, last was %v", obj, lastInt) } lastInt = obj - case uint: + case uint64: if obj <= lastUint { t.Errorf("got %v (uint) out of order, last was %v", obj, lastUint) } else { @@ -57,81 +70,93 @@ func TestFIFO_basic(t *testing.T) { } func TestFIFO_addUpdate(t *testing.T) { - f := NewFIFO() - f.Add("foo", 10) - f.Update("foo", 15) - got := make(chan int, 2) + mkObj := func(name string, val interface{}) testFifoObject { + return testFifoObject{name: name, val: val} + } + + f := NewFIFO(testFifoObjectKeyFunc) + f.Add(mkObj("foo", 10)) + f.Update(mkObj("foo", 15)) + got := make(chan testFifoObject, 2) go func() { for { - got <- f.Pop().(int) + got <- f.Pop().(testFifoObject) } }() first := <-got - if e, a := 15, first; e != a { + if e, a := 15, first.val; e != a { t.Errorf("Didn't get updated value (%v), got %v", e, a) } select { case unexpected := <-got: - t.Errorf("Got second value %v", unexpected) + t.Errorf("Got second value %v", unexpected.val) case <-time.After(50 * time.Millisecond): } - _, exists := f.Get("foo") + _, exists, _ := f.Get(mkObj("foo", "")) if exists { t.Errorf("item did not get removed") } } func TestFIFO_addReplace(t *testing.T) { - f := NewFIFO() - f.Add("foo", 10) - f.Replace(map[string]interface{}{"foo": 15}) - got := make(chan int, 2) + mkObj := func(name string, val interface{}) testFifoObject { + return testFifoObject{name: name, val: val} + } + + f := NewFIFO(testFifoObjectKeyFunc) + f.Add(mkObj("foo", 10)) + f.Replace([]interface{}{mkObj("foo", 15)}) + got := make(chan testFifoObject, 2) go func() { for { - got <- f.Pop().(int) + got <- f.Pop().(testFifoObject) } }() first := <-got - if e, a := 15, first; e != a { + if e, a := 15, first.val; e != a { t.Errorf("Didn't get updated value (%v), got %v", e, a) } select { case unexpected := <-got: - t.Errorf("Got second value %v", unexpected) + t.Errorf("Got second value %v", unexpected.val) case <-time.After(50 * time.Millisecond): } - _, exists := f.Get("foo") + _, exists, _ := f.Get(mkObj("foo", "")) if exists { t.Errorf("item did not get removed") } } func TestFIFO_detectLineJumpers(t *testing.T) { - f := NewFIFO() + mkObj := func(name string, val interface{}) testFifoObject { + return testFifoObject{name: name, val: val} + } + + f := NewFIFO(testFifoObjectKeyFunc) - f.Add("foo", 10) - f.Add("bar", 1) - f.Add("foo", 11) - f.Add("foo", 13) - f.Add("zab", 30) + f.Add(mkObj("foo", 10)) + f.Add(mkObj("bar", 1)) + f.Add(mkObj("foo", 11)) + f.Add(mkObj("foo", 13)) + f.Add(mkObj("zab", 30)) - if e, a := 13, f.Pop().(int); a != e { + if e, a := 13, f.Pop().(testFifoObject).val; a != e { t.Fatalf("expected %d, got %d", e, a) } - f.Add("foo", 14) // ensure foo doesn't jump back in line + f.Add(mkObj("foo", 14)) // ensure foo doesn't jump back in line - if e, a := 1, f.Pop().(int); a != e { + if e, a := 1, f.Pop().(testFifoObject).val; a != e { t.Fatalf("expected %d, got %d", e, a) } - if e, a := 30, f.Pop().(int); a != e { + if e, a := 30, f.Pop().(testFifoObject).val; a != e { t.Fatalf("expected %d, got %d", e, a) } - if e, a := 14, f.Pop().(int); a != e { + if e, a := 14, f.Pop().(testFifoObject).val; a != e { t.Fatalf("expected %d, got %d", e, a) } } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/listers.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/listers.go index a8eb8f57700b..b58a79e16cc1 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/listers.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/listers.go @@ -69,10 +69,17 @@ func (s *StoreToNodeLister) List() (machines api.NodeList, err error) { // rather than a method of StoreToNodeLister. // GetNodeInfo returns cached data for the minion 'id'. func (s *StoreToNodeLister) GetNodeInfo(id string) (*api.Node, error) { - if minion, ok := s.Get(id); ok { - return minion.(*api.Node), nil + minion, exists, err := s.Get(&api.Node{ObjectMeta: api.ObjectMeta{Name: id}}) + + if err != nil { + return nil, fmt.Errorf("error retrieving minion '%v' from cache: %v", id, err) + } + + if !exists { + return nil, fmt.Errorf("minion '%v' is not in cache", id) } - return nil, fmt.Errorf("minion '%v' is not in cache", id) + + return minion.(*api.Node), nil } // StoreToServiceLister makes a Store that has the List method of the client.ServiceInterface diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/listers_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/listers_test.go index 42f8cd058310..eded9f5f676d 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/listers_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/listers_test.go @@ -25,10 +25,10 @@ import ( ) func TestStoreToMinionLister(t *testing.T) { - store := NewStore() + store := NewStore(MetaNamespaceKeyFunc) ids := util.NewStringSet("foo", "bar", "baz") for id := range ids { - store.Add(id, &api.Node{ObjectMeta: api.ObjectMeta{Name: id}}) + store.Add(&api.Node{ObjectMeta: api.ObjectMeta{Name: id}}) } sml := StoreToNodeLister{store} @@ -46,10 +46,10 @@ func TestStoreToMinionLister(t *testing.T) { } func TestStoreToPodLister(t *testing.T) { - store := NewStore() + store := NewStore(MetaNamespaceKeyFunc) ids := []string{"foo", "bar", "baz"} for _, id := range ids { - store.Add(id, &api.Pod{ + store.Add(&api.Pod{ ObjectMeta: api.ObjectMeta{ Name: id, Labels: map[string]string{"name": id}, diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/poller.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/poller.go index deb708320de6..4ffd6732cb49 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/poller.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/poller.go @@ -27,7 +27,7 @@ import ( // one object at a time. type Enumerator interface { Len() int - Get(index int) (ID string, object interface{}) + Get(index int) (object interface{}) } // GetFunc should return an enumerator that you wish the Poller to proccess. @@ -76,14 +76,11 @@ func (p *Poller) run() { } func (p *Poller) sync(e Enumerator) { - current := p.store.ContainedIDs() + items := []interface{}{} for i := 0; i < e.Len(); i++ { - id, object := e.Get(i) - p.store.Update(id, object) - current.Delete(id) - } - // Delete all the objects not found. - for id := range current { - p.store.Delete(id) + object := e.Get(i) + items = append(items, object) } + + p.store.Replace(items) } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/poller_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/poller_test.go index 92a75f2f6209..2c8b240b71b9 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/poller_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/poller_test.go @@ -23,6 +23,10 @@ import ( "time" ) +func testPairKeyFunc(obj interface{}) (string, error) { + return obj.(testPair).id, nil +} + type testPair struct { id string obj interface{} @@ -30,8 +34,8 @@ type testPair struct { type testEnumerator []testPair func (t testEnumerator) Len() int { return len(t) } -func (t testEnumerator) Get(i int) (string, interface{}) { - return t[i].id, t[i].obj +func (t testEnumerator) Get(i int) interface{} { + return t[i] } func TestPoller_sync(t *testing.T) { @@ -64,28 +68,35 @@ func TestPoller_sync(t *testing.T) { } for testCase, item := range table { - s := NewStore() + s := NewStore(testPairKeyFunc) // This is a unit test for the sync function, hence the nil getFunc. p := NewPoller(nil, 0, s) for line, pairs := range item.steps { p.sync(testEnumerator(pairs)) - ids := s.ContainedIDs() + list := s.List() for _, pair := range pairs { - if !ids.Has(pair.id) { - t.Errorf("%v, %v: expected to find entry for %v, but did not.", testCase, line, pair.id) + foundInList := false + for _, listItem := range list { + id, _ := testPairKeyFunc(listItem) + if pair.id == id { + foundInList = true + } + } + if !foundInList { + t.Errorf("%v, %v: expected to find list entry for %v, but did not.", testCase, line, pair.id) continue } - found, ok := s.Get(pair.id) + found, ok, _ := s.Get(pair) if !ok { t.Errorf("%v, %v: unexpected absent entry for %v", testCase, line, pair.id) continue } - if e, a := pair.obj, found; !reflect.DeepEqual(e, a) { + if e, a := pair.obj, found.(testPair).obj; !reflect.DeepEqual(e, a) { t.Errorf("%v, %v: expected %v, got %v for %v", testCase, line, e, a, pair.id) } } - if e, a := len(pairs), len(ids); e != a { + if e, a := len(pairs), len(list); e != a { t.Errorf("%v, %v: expected len %v, got %v", testCase, line, e, a) } } @@ -93,7 +104,7 @@ func TestPoller_sync(t *testing.T) { } func TestPoller_Run(t *testing.T) { - s := NewStore() + s := NewStore(testPairKeyFunc) const count = 10 var called = 0 done := make(chan struct{}) @@ -113,7 +124,7 @@ func TestPoller_Run(t *testing.T) { <-done // We never added anything, verify that. - if e, a := 0, len(s.ContainedIDs()); e != a { + if e, a := 0, len(s.List()); e != a { t.Errorf("expected %v, got %v", e, a) } } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/reflector.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/reflector.go index 68ae3f22b057..f484b3a2bafe 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/reflector.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/reflector.go @@ -18,7 +18,6 @@ package cache import ( "errors" - "fmt" "io" "reflect" "time" @@ -97,8 +96,7 @@ func (r *Reflector) listAndWatch() { glog.Errorf("Unable to understand list result %#v (%v)", list, err) return } - err = r.syncWith(items) - if err != nil { + if err := r.syncWith(items); err != nil { glog.Errorf("Unable to sync list result: %v", err) return } @@ -125,17 +123,12 @@ func (r *Reflector) listAndWatch() { // syncWith replaces the store's items with the given list. func (r *Reflector) syncWith(items []runtime.Object) error { - found := map[string]interface{}{} + found := make([]interface{}, 0, len(items)) for _, item := range items { - meta, err := meta.Accessor(item) - if err != nil { - return fmt.Errorf("unexpected item in list: %v", err) - } - found[meta.Name()] = item + found = append(found, item) } - r.store.Replace(found) - return nil + return r.store.Replace(found) } // watchHandler watches w and keeps *resourceVersion up to date. @@ -161,14 +154,14 @@ func (r *Reflector) watchHandler(w watch.Interface, resourceVersion *string) err } switch event.Type { case watch.Added: - r.store.Add(meta.Name(), event.Object) + r.store.Add(event.Object) case watch.Modified: - r.store.Update(meta.Name(), event.Object) + r.store.Update(event.Object) case watch.Deleted: // TODO: Will any consumers need access to the "last known // state", which is passed in event.Object? If so, may need // to change this. - r.store.Delete(meta.Name()) + r.store.Delete(event.Object) default: glog.Errorf("unable to understand watch event %#v", event) } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/reflector_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/reflector_test.go index 39118a5034de..38f5a6eaaae9 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/reflector_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/reflector_test.go @@ -37,7 +37,7 @@ func (t *testLW) Watch(resourceVersion string) (watch.Interface, error) { } func TestReflector_watchHandlerError(t *testing.T) { - s := NewStore() + s := NewStore(MetaNamespaceKeyFunc) g := NewReflector(&testLW{}, &api.Pod{}, s) fw := watch.NewFake() go func() { @@ -51,11 +51,11 @@ func TestReflector_watchHandlerError(t *testing.T) { } func TestReflector_watchHandler(t *testing.T) { - s := NewStore() + s := NewStore(MetaNamespaceKeyFunc) g := NewReflector(&testLW{}, &api.Pod{}, s) fw := watch.NewFake() - s.Add("foo", &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}) - s.Add("bar", &api.Pod{ObjectMeta: api.ObjectMeta{Name: "bar"}}) + s.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}) + s.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "bar"}}) go func() { fw.Add(&api.Service{ObjectMeta: api.ObjectMeta{Name: "rejected"}}) fw.Delete(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}) @@ -69,26 +69,29 @@ func TestReflector_watchHandler(t *testing.T) { t.Errorf("unexpected error %v", err) } + mkPod := func(id string, rv string) *api.Pod { + return &api.Pod{ObjectMeta: api.ObjectMeta{Name: id, ResourceVersion: rv}} + } + table := []struct { - ID string - RV string + Pod *api.Pod exists bool }{ - {"foo", "", false}, - {"rejected", "", false}, - {"bar", "55", true}, - {"baz", "32", true}, + {mkPod("foo", ""), false}, + {mkPod("rejected", ""), false}, + {mkPod("bar", "55"), true}, + {mkPod("baz", "32"), true}, } for _, item := range table { - obj, exists := s.Get(item.ID) + obj, exists, _ := s.Get(item.Pod) if e, a := item.exists, exists; e != a { - t.Errorf("%v: expected %v, got %v", item.ID, e, a) + t.Errorf("%v: expected %v, got %v", item.Pod, e, a) } if !exists { continue } - if e, a := item.RV, obj.(*api.Pod).ResourceVersion; e != a { - t.Errorf("%v: expected %v, got %v", item.ID, e, a) + if e, a := item.Pod.ResourceVersion, obj.(*api.Pod).ResourceVersion; e != a { + t.Errorf("%v: expected %v, got %v", item.Pod, e, a) } } @@ -121,7 +124,7 @@ func TestReflector_listAndWatch(t *testing.T) { return &api.PodList{ListMeta: api.ListMeta{ResourceVersion: "1"}}, nil }, } - s := NewFIFO() + s := NewFIFO(MetaNamespaceKeyFunc) r := NewReflector(lw, &api.Pod{}, s) go r.listAndWatch() @@ -200,7 +203,7 @@ func TestReflector_listAndWatchWithErrors(t *testing.T) { }, } - s := NewFIFO() + s := NewFIFO(MetaNamespaceKeyFunc) for line, item := range table { if item.list != nil { // Test that the list is what currently exists in the store. diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/store.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/store.go index 6e86aa22ad89..acea6764a2c0 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/store.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/store.go @@ -17,53 +17,89 @@ limitations under the License. package cache import ( + "fmt" "sync" - "github.com/GoogleCloudPlatform/kubernetes/pkg/util" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta" ) // Store is a generic object storage interface. Reflector knows how to watch a server // and update a store. A generic store is provided, which allows Reflector to be used // as a local caching system, and an LRU store, which allows Reflector to work like a // queue of items yet to be processed. +// +// Store makes no assumptions about stored object identity; it is the responsibility +// of a Store implementation to provide a mechanism to correctly key objects and to +// define the contract for obtaining objects by some arbitrary key type. type Store interface { - Add(id string, obj interface{}) - Update(id string, obj interface{}) - Delete(id string) + Add(obj interface{}) error + Update(obj interface{}) error + Delete(obj interface{}) error List() []interface{} - ContainedIDs() util.StringSet - Get(id string) (item interface{}, exists bool) + Get(obj interface{}) (item interface{}, exists bool, err error) // Replace will delete the contents of the store, using instead the - // given map. Store takes ownership of the map, you should not reference + // given list. Store takes ownership of the list, you should not reference // it after calling this function. - Replace(idToObj map[string]interface{}) + Replace([]interface{}) error +} + +// KeyFunc knows how to make a key from an object. Implementations should be deterministic. +type KeyFunc func(obj interface{}) (string, error) + +// MetaNamespaceKeyFunc is a convenient default KeyFunc which knows how to make +// keys for API objects which implement meta.Interface. +// The key uses the format: / +func MetaNamespaceKeyFunc(obj interface{}) (string, error) { + meta, err := meta.Accessor(obj) + if err != nil { + return "", fmt.Errorf("object has no meta: %v", err) + } + return meta.Namespace() + "/" + meta.Name(), nil } type cache struct { lock sync.RWMutex items map[string]interface{} + // keyFunc is used to make the key for objects stored in and retrieved from items, and + // should be deterministic. + keyFunc KeyFunc } // Add inserts an item into the cache. -func (c *cache) Add(id string, obj interface{}) { +func (c *cache) Add(obj interface{}) error { + id, err := c.keyFunc(obj) + if err != nil { + return fmt.Errorf("couldn't create key for object: %v", err) + } c.lock.Lock() defer c.lock.Unlock() c.items[id] = obj + return nil } // Update sets an item in the cache to its updated state. -func (c *cache) Update(id string, obj interface{}) { +func (c *cache) Update(obj interface{}) error { + id, err := c.keyFunc(obj) + if err != nil { + return fmt.Errorf("couldn't create key for object: %v", err) + } c.lock.Lock() defer c.lock.Unlock() c.items[id] = obj + return nil } // Delete removes an item from the cache. -func (c *cache) Delete(id string) { +func (c *cache) Delete(obj interface{}) error { + id, err := c.keyFunc(obj) + if err != nil { + return fmt.Errorf("couldn't create key for object: %v", err) + } c.lock.Lock() defer c.lock.Unlock() delete(c.items, id) + return nil } // List returns a list of all the items. @@ -78,38 +114,39 @@ func (c *cache) List() []interface{} { return list } -// ContainedIDs returns a util.StringSet containing all IDs of the stored items. -// This is a snapshot of a moment in time, and one should keep in mind that -// other go routines can add or remove items after you call this. -func (c *cache) ContainedIDs() util.StringSet { - c.lock.RLock() - defer c.lock.RUnlock() - set := util.StringSet{} - for id := range c.items { - set.Insert(id) - } - return set -} - // Get returns the requested item, or sets exists=false. // Get is completely threadsafe as long as you treat all items as immutable. -func (c *cache) Get(id string) (item interface{}, exists bool) { +func (c *cache) Get(obj interface{}) (item interface{}, exists bool, err error) { + id, _ := c.keyFunc(obj) + if err != nil { + return nil, false, fmt.Errorf("couldn't create key for object: %v", err) + } c.lock.RLock() defer c.lock.RUnlock() item, exists = c.items[id] - return item, exists + return item, exists, nil } -// Replace will delete the contents of 'c', using instead the given map. -// 'c' takes ownership of the map, you should not reference the map again +// Replace will delete the contents of 'c', using instead the given list. +// 'c' takes ownership of the list, you should not reference the list again // after calling this function. -func (c *cache) Replace(idToObj map[string]interface{}) { +func (c *cache) Replace(list []interface{}) error { + items := map[string]interface{}{} + for _, item := range list { + key, err := c.keyFunc(item) + if err != nil { + return fmt.Errorf("couldn't create key for object: %v", err) + } + items[key] = item + } + c.lock.Lock() defer c.lock.Unlock() - c.items = idToObj + c.items = items + return nil } // NewStore returns a Store implemented simply with a map and a lock. -func NewStore() Store { - return &cache{items: map[string]interface{}{}} +func NewStore(keyFunc KeyFunc) Store { + return &cache{items: map[string]interface{}{}, keyFunc: keyFunc} } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/store_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/store_test.go index 244fc9ff0464..3d29aec1f1ca 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/store_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/store_test.go @@ -24,63 +24,58 @@ import ( // Test public interface func doTestStore(t *testing.T, store Store) { - store.Add("foo", "bar") - if item, ok := store.Get("foo"); !ok { + mkObj := func(id string, val string) testStoreObject { + return testStoreObject{id: id, val: val} + } + + store.Add(mkObj("foo", "bar")) + if item, ok, _ := store.Get(mkObj("foo", "")); !ok { t.Errorf("didn't find inserted item") } else { - if e, a := "bar", item.(string); e != a { + if e, a := "bar", item.(testStoreObject).val; e != a { t.Errorf("expected %v, got %v", e, a) } } - store.Update("foo", "baz") - if item, ok := store.Get("foo"); !ok { + store.Update(mkObj("foo", "baz")) + if item, ok, _ := store.Get(mkObj("foo", "")); !ok { t.Errorf("didn't find inserted item") } else { - if e, a := "baz", item.(string); e != a { + if e, a := "baz", item.(testStoreObject).val; e != a { t.Errorf("expected %v, got %v", e, a) } } - store.Delete("foo") - if _, ok := store.Get("foo"); ok { + store.Delete(mkObj("foo", "")) + if _, ok, _ := store.Get(mkObj("foo", "")); ok { t.Errorf("found deleted item??") } // Test List. - store.Add("a", "b") - store.Add("c", "d") - store.Add("e", "e") + store.Add(mkObj("a", "b")) + store.Add(mkObj("c", "d")) + store.Add(mkObj("e", "e")) { found := util.StringSet{} for _, item := range store.List() { - found.Insert(item.(string)) + found.Insert(item.(testStoreObject).val) } if !found.HasAll("b", "d", "e") { - t.Errorf("missing items") + t.Errorf("missing items, found: %v", found) } if len(found) != 3 { t.Errorf("extra items") } - - // Check that ID list is correct. - ids := store.ContainedIDs() - if !ids.HasAll("a", "c", "e") { - t.Errorf("missing items") - } - if len(ids) != 3 { - t.Errorf("extra items") - } } // Test Replace. - store.Replace(map[string]interface{}{ - "foo": "foo", - "bar": "bar", + store.Replace([]interface{}{ + mkObj("foo", "foo"), + mkObj("bar", "bar"), }) { found := util.StringSet{} for _, item := range store.List() { - found.Insert(item.(string)) + found.Insert(item.(testStoreObject).val) } if !found.HasAll("foo", "bar") { t.Errorf("missing items") @@ -88,27 +83,27 @@ func doTestStore(t *testing.T, store Store) { if len(found) != 2 { t.Errorf("extra items") } - - // Check that ID list is correct. - ids := store.ContainedIDs() - if !ids.HasAll("foo", "bar") { - t.Errorf("missing items") - } - if len(ids) != 2 { - t.Errorf("extra items") - } } } +func testStoreKeyFunc(obj interface{}) (string, error) { + return obj.(testStoreObject).id, nil +} + +type testStoreObject struct { + id string + val string +} + func TestCache(t *testing.T) { - doTestStore(t, NewStore()) + doTestStore(t, NewStore(testStoreKeyFunc)) } func TestFIFOCache(t *testing.T) { - doTestStore(t, NewFIFO()) + doTestStore(t, NewFIFO(testStoreKeyFunc)) } func TestUndeltaStore(t *testing.T) { nop := func([]interface{}) {} - doTestStore(t, NewUndeltaStore(nop)) + doTestStore(t, NewUndeltaStore(nop, testStoreKeyFunc)) } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/undelta_store.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/undelta_store.go index 9859c5ccb483..09299fbd34a7 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/undelta_store.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/undelta_store.go @@ -16,10 +16,6 @@ limitations under the License. package cache -import ( - "github.com/GoogleCloudPlatform/kubernetes/pkg/util" -) - // UndeltaStore listens to incremental updates and sends complete state on every change. // It implements the Store interface so that it can receive a stream of mirrored objects // from Reflector. Whenever it receives any complete (Store.Replace) or incremental change @@ -46,36 +42,45 @@ var _ Store = &UndeltaStore{} // 4 Store.List() -> [a,b] // 5 Store.List() -> [a,b] -func (u *UndeltaStore) Add(id string, obj interface{}) { - u.ActualStore.Add(id, obj) +func (u *UndeltaStore) Add(obj interface{}) error { + if err := u.ActualStore.Add(obj); err != nil { + return err + } u.PushFunc(u.ActualStore.List()) + return nil } -func (u *UndeltaStore) Update(id string, obj interface{}) { - u.ActualStore.Update(id, obj) +func (u *UndeltaStore) Update(obj interface{}) error { + if err := u.ActualStore.Update(obj); err != nil { + return err + } u.PushFunc(u.ActualStore.List()) + return nil } -func (u *UndeltaStore) Delete(id string) { - u.ActualStore.Delete(id) +func (u *UndeltaStore) Delete(obj interface{}) error { + if err := u.ActualStore.Delete(obj); err != nil { + return err + } u.PushFunc(u.ActualStore.List()) + return nil } func (u *UndeltaStore) List() []interface{} { return u.ActualStore.List() } -func (u *UndeltaStore) ContainedIDs() util.StringSet { - return u.ActualStore.ContainedIDs() -} -func (u *UndeltaStore) Get(id string) (item interface{}, exists bool) { - return u.ActualStore.Get(id) +func (u *UndeltaStore) Get(obj interface{}) (item interface{}, exists bool, err error) { + return u.ActualStore.Get(obj) } -func (u *UndeltaStore) Replace(idToObj map[string]interface{}) { - u.ActualStore.Replace(idToObj) +func (u *UndeltaStore) Replace(list []interface{}) error { + if err := u.ActualStore.Replace(list); err != nil { + return err + } u.PushFunc(u.ActualStore.List()) + return nil } // NewUndeltaStore returns an UndeltaStore implemented with a Store. -func NewUndeltaStore(pushFunc func([]interface{})) *UndeltaStore { +func NewUndeltaStore(pushFunc func([]interface{}), keyFunc KeyFunc) *UndeltaStore { return &UndeltaStore{ - ActualStore: NewStore(), + ActualStore: NewStore(keyFunc), PushFunc: pushFunc, } } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/undelta_store_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/undelta_store_test.go index cae33bab2f4c..e52e07820838 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/undelta_store_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/undelta_store_test.go @@ -24,15 +24,28 @@ import ( // store_test.go checks that UndeltaStore conforms to the Store interface // behavior. This test just tests that it calls the push func in addition. -type t struct{ int } +type testUndeltaObject struct { + name string + val interface{} +} + +func testUndeltaKeyFunc(obj interface{}) (string, error) { + return obj.(testUndeltaObject).name, nil +} +/* var ( o1 interface{} = t{1} o2 interface{} = t{2} l1 []interface{} = []interface{}{t{1}} ) +*/ func TestUpdateCallsPush(t *testing.T) { + mkObj := func(name string, val interface{}) testUndeltaObject { + return testUndeltaObject{name: name, val: val} + } + var got []interface{} var callcount int = 0 push := func(m []interface{}) { @@ -40,19 +53,25 @@ func TestUpdateCallsPush(t *testing.T) { got = m } - u := NewUndeltaStore(push) + u := NewUndeltaStore(push, testUndeltaKeyFunc) - u.Add("a", o2) - u.Update("a", o1) + u.Add(mkObj("a", 2)) + u.Update(mkObj("a", 1)) if callcount != 2 { t.Errorf("Expected 2 calls, got %d", callcount) } - if !reflect.DeepEqual(l1, got) { - t.Errorf("Expected %#v, Got %#v", l1, got) + + l := []interface{}{mkObj("a", 1)} + if !reflect.DeepEqual(l, got) { + t.Errorf("Expected %#v, Got %#v", l, got) } } func TestDeleteCallsPush(t *testing.T) { + mkObj := func(name string, val interface{}) testUndeltaObject { + return testUndeltaObject{name: name, val: val} + } + var got []interface{} var callcount int = 0 push := func(m []interface{}) { @@ -60,10 +79,10 @@ func TestDeleteCallsPush(t *testing.T) { got = m } - u := NewUndeltaStore(push) + u := NewUndeltaStore(push, testUndeltaKeyFunc) - u.Add("a", o2) - u.Delete("a") + u.Add(mkObj("a", 2)) + u.Delete(mkObj("a", "")) if callcount != 2 { t.Errorf("Expected 2 calls, got %d", callcount) } @@ -78,15 +97,18 @@ func TestReadsDoNotCallPush(t *testing.T) { t.Errorf("Unexpected call to push!") } - u := NewUndeltaStore(push) + u := NewUndeltaStore(push, testUndeltaKeyFunc) // These should not call push. _ = u.List() - _ = u.ContainedIDs() - _, _ = u.Get("1") + _, _, _ = u.Get(testUndeltaObject{"a", ""}) } func TestReplaceCallsPush(t *testing.T) { + mkObj := func(name string, val interface{}) testUndeltaObject { + return testUndeltaObject{name: name, val: val} + } + var got []interface{} var callcount int = 0 push := func(m []interface{}) { @@ -94,16 +116,15 @@ func TestReplaceCallsPush(t *testing.T) { got = m } - u := NewUndeltaStore(push) + u := NewUndeltaStore(push, testUndeltaKeyFunc) - m := make(map[string]interface{}) - m["1"] = o1 + m := []interface{}{mkObj("a", 1)} u.Replace(m) if callcount != 1 { t.Errorf("Expected 1 calls, got %d", callcount) } - expected := l1 + expected := []interface{}{mkObj("a", 1)} if !reflect.DeepEqual(expected, got) { t.Errorf("Expected %#v, Got %#v", expected, got) } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/client.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/client.go index 8a92fc6ce3f1..6fddce33a205 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/client.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/client.go @@ -37,6 +37,9 @@ type Interface interface { VersionInterface NodesInterface EventNamespacer + LimitRangesNamespacer + ResourceQuotasNamespacer + ResourceQuotaUsagesNamespacer } func (c *Client) ReplicationControllers(namespace string) ReplicationControllerInterface { @@ -63,6 +66,18 @@ func (c *Client) Services(namespace string) ServiceInterface { return newServices(c, namespace) } +func (c *Client) LimitRanges(namespace string) LimitRangeInterface { + return newLimitRanges(c, namespace) +} + +func (c *Client) ResourceQuotas(namespace string) ResourceQuotaInterface { + return newResourceQuotas(c, namespace) +} + +func (c *Client) ResourceQuotaUsages(namespace string) ResourceQuotaUsageInterface { + return newResourceQuotaUsages(c, namespace) +} + // VersionInterface has a method to retrieve the server version. type VersionInterface interface { ServerVersion() (*version.Info, error) diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/client_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/client_test.go index 7bfff9bfade5..c9e7d4f713ef 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/client_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/client_test.go @@ -759,6 +759,27 @@ func TestDeleteMinion(t *testing.T) { c.Validate(t, nil, err) } +func TestUpdateMinion(t *testing.T) { + requestMinion := &api.Node{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + ResourceVersion: "1", + }, + Spec: api.NodeSpec{ + Capacity: api.ResourceList{ + api.ResourceCPU: resource.MustParse("1000m"), + api.ResourceMemory: resource.MustParse("1Mi"), + }, + }, + } + c := &testClient{ + Request: testRequest{Method: "PUT", Path: "/minions/foo"}, + Response: Response{StatusCode: 200, Body: requestMinion}, + } + response, err := c.Setup().Nodes().Update(requestMinion) + c.Validate(t, response, err) +} + func TestNewMinionPath(t *testing.T) { c := &testClient{ Request: testRequest{Method: "DELETE", Path: "/nodes/foo"}, diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/loader.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/loader.go index dc8696b10240..7d2224ec428b 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/loader.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/loader.go @@ -60,6 +60,8 @@ func NewClientConfigLoadingRules() *ClientConfigLoadingRules { // This means that the first file to set CurrentContext will have its context preserved. It also means // that if two files specify a "red-user", only values from the first file's red-user are used. Even // non-conflicting entries from the second file's "red-user" are discarded. +// Relative paths inside of the .kubeconfig files are resolved against the .kubeconfig file's parent folder +// and only absolute file paths are returned. func (rules *ClientConfigLoadingRules) Load() (*clientcmdapi.Config, error) { config := clientcmdapi.NewConfig() diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/loader_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/loader_test.go index dc3eb86bd670..018d4df809e3 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/loader_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/loader_test.go @@ -20,6 +20,9 @@ import ( "fmt" "io/ioutil" "os" + "path" + "path/filepath" + "testing" "github.com/ghodss/yaml" @@ -71,6 +74,107 @@ var ( } ) +func TestResolveRelativePaths(t *testing.T) { + pathResolutionConfig1 := clientcmdapi.Config{ + AuthInfos: map[string]clientcmdapi.AuthInfo{ + "relative-user-1": {ClientCertificate: "relative/client/cert", ClientKey: "../relative/client/key", AuthPath: "../../relative/auth/path"}, + "absolute-user-1": {ClientCertificate: "/absolute/client/cert", ClientKey: "/absolute/client/key", AuthPath: "/absolute/auth/path"}, + }, + Clusters: map[string]clientcmdapi.Cluster{ + "relative-server-1": {CertificateAuthority: "../relative/ca"}, + "absolute-server-1": {CertificateAuthority: "/absolute/ca"}, + }, + } + pathResolutionConfig2 := clientcmdapi.Config{ + AuthInfos: map[string]clientcmdapi.AuthInfo{ + "relative-user-2": {ClientCertificate: "relative/client/cert2", ClientKey: "../relative/client/key2", AuthPath: "../../relative/auth/path2"}, + "absolute-user-2": {ClientCertificate: "/absolute/client/cert2", ClientKey: "/absolute/client/key2", AuthPath: "/absolute/auth/path2"}, + }, + Clusters: map[string]clientcmdapi.Cluster{ + "relative-server-2": {CertificateAuthority: "../relative/ca2"}, + "absolute-server-2": {CertificateAuthority: "/absolute/ca2"}, + }, + } + + configDir1, _ := ioutil.TempDir("", "") + configFile1 := path.Join(configDir1, ".kubeconfig") + configDir1, _ = filepath.Abs(configDir1) + defer os.Remove(configFile1) + configDir2, _ := ioutil.TempDir("", "") + configDir2, _ = ioutil.TempDir(configDir2, "") + configFile2 := path.Join(configDir2, ".kubeconfig") + configDir2, _ = filepath.Abs(configDir2) + defer os.Remove(configFile2) + + WriteToFile(pathResolutionConfig1, configFile1) + WriteToFile(pathResolutionConfig2, configFile2) + + loadingRules := ClientConfigLoadingRules{ + CommandLinePath: configFile1, + EnvVarPath: configFile2, + } + + mergedConfig, err := loadingRules.Load() + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + + foundClusterCount := 0 + for key, cluster := range mergedConfig.Clusters { + if key == "relative-server-1" { + foundClusterCount++ + matchStringArg(path.Join(configDir1, pathResolutionConfig1.Clusters["relative-server-1"].CertificateAuthority), cluster.CertificateAuthority, t) + } + if key == "relative-server-2" { + foundClusterCount++ + matchStringArg(path.Join(configDir2, pathResolutionConfig2.Clusters["relative-server-2"].CertificateAuthority), cluster.CertificateAuthority, t) + } + if key == "absolute-server-1" { + foundClusterCount++ + matchStringArg(pathResolutionConfig1.Clusters["absolute-server-1"].CertificateAuthority, cluster.CertificateAuthority, t) + } + if key == "absolute-server-2" { + foundClusterCount++ + matchStringArg(pathResolutionConfig2.Clusters["absolute-server-2"].CertificateAuthority, cluster.CertificateAuthority, t) + } + } + if foundClusterCount != 4 { + t.Errorf("Expected 4 clusters, found %v: %v", foundClusterCount, mergedConfig.Clusters) + } + + foundAuthInfoCount := 0 + for key, authInfo := range mergedConfig.AuthInfos { + if key == "relative-user-1" { + foundAuthInfoCount++ + matchStringArg(path.Join(configDir1, pathResolutionConfig1.AuthInfos["relative-user-1"].ClientCertificate), authInfo.ClientCertificate, t) + matchStringArg(path.Join(configDir1, pathResolutionConfig1.AuthInfos["relative-user-1"].ClientKey), authInfo.ClientKey, t) + matchStringArg(path.Join(configDir1, pathResolutionConfig1.AuthInfos["relative-user-1"].AuthPath), authInfo.AuthPath, t) + } + if key == "relative-user-2" { + foundAuthInfoCount++ + matchStringArg(path.Join(configDir2, pathResolutionConfig2.AuthInfos["relative-user-2"].ClientCertificate), authInfo.ClientCertificate, t) + matchStringArg(path.Join(configDir2, pathResolutionConfig2.AuthInfos["relative-user-2"].ClientKey), authInfo.ClientKey, t) + matchStringArg(path.Join(configDir2, pathResolutionConfig2.AuthInfos["relative-user-2"].AuthPath), authInfo.AuthPath, t) + } + if key == "absolute-user-1" { + foundAuthInfoCount++ + matchStringArg(pathResolutionConfig1.AuthInfos["absolute-user-1"].ClientCertificate, authInfo.ClientCertificate, t) + matchStringArg(pathResolutionConfig1.AuthInfos["absolute-user-1"].ClientKey, authInfo.ClientKey, t) + matchStringArg(pathResolutionConfig1.AuthInfos["absolute-user-1"].AuthPath, authInfo.AuthPath, t) + } + if key == "absolute-user-2" { + foundAuthInfoCount++ + matchStringArg(pathResolutionConfig2.AuthInfos["absolute-user-2"].ClientCertificate, authInfo.ClientCertificate, t) + matchStringArg(pathResolutionConfig2.AuthInfos["absolute-user-2"].ClientKey, authInfo.ClientKey, t) + matchStringArg(pathResolutionConfig2.AuthInfos["absolute-user-2"].AuthPath, authInfo.AuthPath, t) + } + } + if foundAuthInfoCount != 4 { + t.Errorf("Expected 4 users, found %v: %v", foundAuthInfoCount, mergedConfig.AuthInfos) + } + +} + func ExampleMergingSomeWithConflict() { commandLineFile, _ := ioutil.TempFile("", "") defer os.Remove(commandLineFile.Name()) diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/overrides.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/overrides.go index b22e31664b6d..f6309c98c5ec 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/overrides.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/overrides.go @@ -51,11 +51,10 @@ type AuthOverrideFlags struct { // ContextOverrideFlags holds the flag names to be used for binding command line flags for Cluster objects type ContextOverrideFlags struct { - ClusterName string - AuthInfoName string - Namespace string - NamespaceShort string - NamespacePath string + ClusterName string + AuthInfoName string + Namespace string + NamespacePath string } // ClusterOverride holds the flag names to be used for binding command line flags for Cluster objects @@ -151,6 +150,6 @@ func BindOverrideFlags(overrides *ConfigOverrides, flags *pflag.FlagSet, flagNam func BindContextFlags(contextInfo *clientcmdapi.Context, flags *pflag.FlagSet, flagNames ContextOverrideFlags) { flags.StringVar(&contextInfo.Cluster, flagNames.ClusterName, "", "The name of the kubeconfig cluster to use") flags.StringVar(&contextInfo.AuthInfo, flagNames.AuthInfoName, "", "The name of the kubeconfig user to use") - flags.StringVarP(&contextInfo.Namespace, flagNames.Namespace, flagNames.NamespaceShort, "", "If present, the namespace scope for this CLI request.") + flags.StringVar(&contextInfo.Namespace, flagNames.Namespace, "", "If present, the namespace scope for this CLI request.") flags.StringVar(&contextInfo.NamespacePath, flagNames.NamespacePath, "", "Path to the namespace info file that holds the namespace context to use for CLI requests.") } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake.go index 7cb4c5d059bc..42bd2e5f36d8 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake.go @@ -34,15 +34,30 @@ type FakeAction struct { // Fake implements Interface. Meant to be embedded into a struct to get a default // implementation. This makes faking out just the method you want to test easier. type Fake struct { - Actions []FakeAction - PodsList api.PodList - Ctrl api.ReplicationController - ServiceList api.ServiceList - EndpointsList api.EndpointsList - MinionsList api.NodeList - EventsList api.EventList - Err error - Watch watch.Interface + Actions []FakeAction + PodsList api.PodList + CtrlList api.ReplicationControllerList + Ctrl api.ReplicationController + ServiceList api.ServiceList + EndpointsList api.EndpointsList + MinionsList api.NodeList + EventsList api.EventList + LimitRangesList api.LimitRangeList + ResourceQuotasList api.ResourceQuotaList + Err error + Watch watch.Interface +} + +func (c *Fake) LimitRanges(namespace string) LimitRangeInterface { + return &FakeLimitRanges{Fake: c, Namespace: namespace} +} + +func (c *Fake) ResourceQuotas(namespace string) ResourceQuotaInterface { + return &FakeResourceQuotas{Fake: c, Namespace: namespace} +} + +func (c *Fake) ResourceQuotaUsages(namespace string) ResourceQuotaUsageInterface { + return &FakeResourceQuotaUsages{Fake: c, Namespace: namespace} } func (c *Fake) ReplicationControllers(namespace string) ReplicationControllerInterface { diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake_limit_ranges.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake_limit_ranges.go new file mode 100644 index 000000000000..9d1c7c237c57 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake_limit_ranges.go @@ -0,0 +1,54 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 client + +import ( + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" +) + +// FakeLimitRanges implements PodsInterface. Meant to be embedded into a struct to get a default +// implementation. This makes faking out just the methods you want to test easier. +type FakeLimitRanges struct { + Fake *Fake + Namespace string +} + +func (c *FakeLimitRanges) List(selector labels.Selector) (*api.LimitRangeList, error) { + c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "list-limitRanges"}) + return api.Scheme.CopyOrDie(&c.Fake.LimitRangesList).(*api.LimitRangeList), nil +} + +func (c *FakeLimitRanges) Get(name string) (*api.LimitRange, error) { + c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "get-limitRange", Value: name}) + return &api.LimitRange{ObjectMeta: api.ObjectMeta{Name: name, Namespace: c.Namespace}}, nil +} + +func (c *FakeLimitRanges) Delete(name string) error { + c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "delete-limitRange", Value: name}) + return nil +} + +func (c *FakeLimitRanges) Create(limitRange *api.LimitRange) (*api.LimitRange, error) { + c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "create-limitRange"}) + return &api.LimitRange{}, nil +} + +func (c *FakeLimitRanges) Update(limitRange *api.LimitRange) (*api.LimitRange, error) { + c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "update-limitRange", Value: limitRange.Name}) + return &api.LimitRange{}, nil +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake_minions.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake_minions.go index aa1d2c049262..d3e195673d06 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake_minions.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake_minions.go @@ -51,3 +51,8 @@ func (c *FakeNodes) Delete(id string) error { c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "delete-minion", Value: id}) return nil } + +func (c *FakeNodes) Update(minion *api.Node) (*api.Node, error) { + c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "update-minion", Value: minion}) + return &api.Node{}, nil +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake_replication_controllers.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake_replication_controllers.go index 589cac62b79f..17a1f02f9df6 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake_replication_controllers.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake_replication_controllers.go @@ -31,7 +31,7 @@ type FakeReplicationControllers struct { func (c *FakeReplicationControllers) List(selector labels.Selector) (*api.ReplicationControllerList, error) { c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "list-controllers"}) - return &api.ReplicationControllerList{}, nil + return api.Scheme.CopyOrDie(&c.Fake.CtrlList).(*api.ReplicationControllerList), nil } func (c *FakeReplicationControllers) Get(name string) (*api.ReplicationController, error) { diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake_resource_quota_usages.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake_resource_quota_usages.go new file mode 100644 index 000000000000..50b733b55ff6 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake_resource_quota_usages.go @@ -0,0 +1,33 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 client + +import ( + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" +) + +// FakeResourceQuotaUsages implements ResourceQuotaUsageInterface. Meant to be embedded into a struct to get a default +// implementation. This makes faking out just the methods you want to test easier. +type FakeResourceQuotaUsages struct { + Fake *Fake + Namespace string +} + +func (c *FakeResourceQuotaUsages) Create(resourceQuotaUsage *api.ResourceQuotaUsage) error { + c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "create-resourceQuotaUsage"}) + return nil +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake_resource_quotas.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake_resource_quotas.go new file mode 100644 index 000000000000..f7b870ed127b --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/fake_resource_quotas.go @@ -0,0 +1,54 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 client + +import ( + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" +) + +// FakeResourceQuotas implements ResourceQuotaInterface. Meant to be embedded into a struct to get a default +// implementation. This makes faking out just the methods you want to test easier. +type FakeResourceQuotas struct { + Fake *Fake + Namespace string +} + +func (c *FakeResourceQuotas) List(selector labels.Selector) (*api.ResourceQuotaList, error) { + c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "list-resourceQuotas"}) + return api.Scheme.CopyOrDie(&c.Fake.ResourceQuotasList).(*api.ResourceQuotaList), nil +} + +func (c *FakeResourceQuotas) Get(name string) (*api.ResourceQuota, error) { + c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "get-resourceQuota", Value: name}) + return &api.ResourceQuota{ObjectMeta: api.ObjectMeta{Name: name, Namespace: c.Namespace}}, nil +} + +func (c *FakeResourceQuotas) Delete(name string) error { + c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "delete-resourceQuota", Value: name}) + return nil +} + +func (c *FakeResourceQuotas) Create(resourceQuota *api.ResourceQuota) (*api.ResourceQuota, error) { + c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "create-resourceQuota"}) + return &api.ResourceQuota{}, nil +} + +func (c *FakeResourceQuotas) Update(resourceQuota *api.ResourceQuota) (*api.ResourceQuota, error) { + c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "update-resourceQuota", Value: resourceQuota.Name}) + return &api.ResourceQuota{}, nil +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/kubelet.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/kubelet.go index 8c1c5b7186b3..c8eea30937fe 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/kubelet.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/kubelet.go @@ -26,7 +26,8 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" - "github.com/GoogleCloudPlatform/kubernetes/pkg/health" + "github.com/GoogleCloudPlatform/kubernetes/pkg/probe" + httprobe "github.com/GoogleCloudPlatform/kubernetes/pkg/probe/http" ) // ErrPodInfoNotAvailable may be returned when the requested pod info is not available. @@ -40,7 +41,7 @@ type KubeletClient interface { // KubeletHealthchecker is an interface for healthchecking kubelets type KubeletHealthChecker interface { - HealthCheck(host string) (health.Status, error) + HealthCheck(host string) (probe.Status, error) } // PodInfoGetter is an interface for things that can get information about a pod's containers. @@ -134,6 +135,9 @@ func (c *HTTPKubeletClient) GetPodStatus(host, podNamespace, podID string) (api. if response.StatusCode == http.StatusNotFound { return status, ErrPodInfoNotAvailable } + if response.StatusCode >= 300 || response.StatusCode < 200 { + return status, fmt.Errorf("kubelet %q server responded with HTTP error code %d for pod %s/%s", host, response.StatusCode, podNamespace, podID) + } body, err := ioutil.ReadAll(response.Body) if err != nil { return status, err @@ -146,8 +150,8 @@ func (c *HTTPKubeletClient) GetPodStatus(host, podNamespace, podID string) (api. return status, nil } -func (c *HTTPKubeletClient) HealthCheck(host string) (health.Status, error) { - return health.DoHTTPCheck(fmt.Sprintf("%s/healthz", c.url(host)), c.Client) +func (c *HTTPKubeletClient) HealthCheck(host string) (probe.Status, error) { + return httprobe.DoHTTPProbe(fmt.Sprintf("%s/healthz", c.url(host)), c.Client) } // FakeKubeletClient is a fake implementation of KubeletClient which returns an error @@ -160,6 +164,6 @@ func (c FakeKubeletClient) GetPodStatus(host, podNamespace string, podID string) return api.PodStatusResult{}, errors.New("Not Implemented") } -func (c FakeKubeletClient) HealthCheck(host string) (health.Status, error) { - return health.Unknown, errors.New("Not Implemented") +func (c FakeKubeletClient) HealthCheck(host string) (probe.Status, error) { + return probe.Unknown, errors.New("Not Implemented") } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/kubelet_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/kubelet_test.go index a36b2986ec21..7d4f720d0e80 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/kubelet_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/kubelet_test.go @@ -26,7 +26,7 @@ import ( "testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - "github.com/GoogleCloudPlatform/kubernetes/pkg/health" + "github.com/GoogleCloudPlatform/kubernetes/pkg/probe" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" ) @@ -118,6 +118,46 @@ func TestHTTPKubeletClientNotFound(t *testing.T) { } } +func TestHTTPKubeletClientError(t *testing.T) { + expectObj := api.PodContainerInfo{ + ContainerInfo: map[string]api.ContainerStatus{ + "myID": {}, + }, + } + _, err := json.Marshal(expectObj) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + + fakeHandler := util.FakeHandler{ + StatusCode: 500, + ResponseBody: "Internal server error", + } + testServer := httptest.NewServer(&fakeHandler) + defer testServer.Close() + + hostURL, err := url.Parse(testServer.URL) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + + parts := strings.Split(hostURL.Host, ":") + + port, err := strconv.Atoi(parts[1]) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + + podInfoGetter := &HTTPKubeletClient{ + Client: http.DefaultClient, + Port: uint(port), + } + _, err = podInfoGetter.GetPodStatus(parts[0], api.NamespaceDefault, "foo") + if err == nil || !strings.Contains(err.Error(), "HTTP error code 500") { + t.Errorf("unexpected error: %v", err) + } +} + func TestNewKubeletClient(t *testing.T) { config := &KubeletConfig{ Port: 9000, @@ -134,8 +174,8 @@ func TestNewKubeletClient(t *testing.T) { host := "127.0.0.1" healthStatus, err := client.HealthCheck(host) - if healthStatus != health.Unhealthy { - t.Errorf("Expected %v and got %v.", health.Unhealthy, healthStatus) + if healthStatus != probe.Failure { + t.Errorf("Expected %v and got %v.", probe.Failure, healthStatus) } if err != nil { t.Error("Expected a nil error") diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/limit_ranges.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/limit_ranges.go new file mode 100644 index 000000000000..fa03c61178e2 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/limit_ranges.go @@ -0,0 +1,94 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 client + +import ( + "errors" + "fmt" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" +) + +// LimitRangesNamespacer has methods to work with LimitRange resources in a namespace +type LimitRangesNamespacer interface { + LimitRanges(namespace string) LimitRangeInterface +} + +// LimitRangeInterface has methods to work with LimitRange resources. +type LimitRangeInterface interface { + List(selector labels.Selector) (*api.LimitRangeList, error) + Get(name string) (*api.LimitRange, error) + Delete(name string) error + Create(limitRange *api.LimitRange) (*api.LimitRange, error) + Update(limitRange *api.LimitRange) (*api.LimitRange, error) +} + +// limitRanges implements LimitRangesNamespacer interface +type limitRanges struct { + r *Client + ns string +} + +// newLimitRanges returns a limitRanges +func newLimitRanges(c *Client, namespace string) *limitRanges { + return &limitRanges{ + r: c, + ns: namespace, + } +} + +// List takes a selector, and returns the list of limitRanges that match that selector. +func (c *limitRanges) List(selector labels.Selector) (result *api.LimitRangeList, err error) { + result = &api.LimitRangeList{} + err = c.r.Get().Namespace(c.ns).Resource("limitRanges").SelectorParam("labels", selector).Do().Into(result) + return +} + +// Get takes the name of the limitRange, and returns the corresponding Pod object, and an error if it occurs +func (c *limitRanges) Get(name string) (result *api.LimitRange, err error) { + if len(name) == 0 { + return nil, errors.New("name is required parameter to Get") + } + + result = &api.LimitRange{} + err = c.r.Get().Namespace(c.ns).Resource("limitRanges").Name(name).Do().Into(result) + return +} + +// Delete takes the name of the limitRange, and returns an error if one occurs +func (c *limitRanges) Delete(name string) error { + return c.r.Delete().Namespace(c.ns).Resource("limitRanges").Name(name).Do().Error() +} + +// Create takes the representation of a limitRange. Returns the server's representation of the limitRange, and an error, if it occurs. +func (c *limitRanges) Create(limitRange *api.LimitRange) (result *api.LimitRange, err error) { + result = &api.LimitRange{} + err = c.r.Post().Namespace(c.ns).Resource("limitRanges").Body(limitRange).Do().Into(result) + return +} + +// Update takes the representation of a limitRange to update. Returns the server's representation of the limitRange, and an error, if it occurs. +func (c *limitRanges) Update(limitRange *api.LimitRange) (result *api.LimitRange, err error) { + result = &api.LimitRange{} + if len(limitRange.ResourceVersion) == 0 { + err = fmt.Errorf("invalid update object, missing resource version: %v", limitRange) + return + } + err = c.r.Put().Namespace(c.ns).Resource("limitRanges").Name(limitRange.Name).Body(limitRange).Do().Into(result) + return +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/limit_ranges_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/limit_ranges_test.go new file mode 100644 index 000000000000..126baa7ac5f6 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/limit_ranges_test.go @@ -0,0 +1,194 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 client + +import ( + "testing" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource" + "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" + //"github.com/GoogleCloudPlatform/kubernetes/pkg/util" +) + +func TestLimitRangeCreate(t *testing.T) { + ns := api.NamespaceDefault + limitRange := &api.LimitRange{ + ObjectMeta: api.ObjectMeta{ + Name: "abc", + }, + Spec: api.LimitRangeSpec{ + Limits: []api.LimitRangeItem{ + { + Type: api.LimitTypePod, + Max: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100"), + api.ResourceMemory: resource.MustParse("10000"), + }, + Min: api.ResourceList{ + api.ResourceCPU: resource.MustParse("0"), + api.ResourceMemory: resource.MustParse("100"), + }, + }, + }, + }, + } + c := &testClient{ + Request: testRequest{ + Method: "POST", + Path: buildResourcePath(ns, "/limitRanges"), + Query: buildQueryValues(ns, nil), + Body: limitRange, + }, + Response: Response{StatusCode: 200, Body: limitRange}, + } + + response, err := c.Setup().LimitRanges(ns).Create(limitRange) + c.Validate(t, response, err) +} + +func TestLimitRangeGet(t *testing.T) { + ns := api.NamespaceDefault + limitRange := &api.LimitRange{ + ObjectMeta: api.ObjectMeta{ + Name: "abc", + }, + Spec: api.LimitRangeSpec{ + Limits: []api.LimitRangeItem{ + { + Type: api.LimitTypePod, + Max: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100"), + api.ResourceMemory: resource.MustParse("10000"), + }, + Min: api.ResourceList{ + api.ResourceCPU: resource.MustParse("0"), + api.ResourceMemory: resource.MustParse("100"), + }, + }, + }, + }, + } + c := &testClient{ + Request: testRequest{ + Method: "GET", + Path: buildResourcePath(ns, "/limitRanges/abc"), + Query: buildQueryValues(ns, nil), + Body: nil, + }, + Response: Response{StatusCode: 200, Body: limitRange}, + } + + response, err := c.Setup().LimitRanges(ns).Get("abc") + c.Validate(t, response, err) +} + +func TestLimitRangeList(t *testing.T) { + ns := api.NamespaceDefault + + limitRangeList := &api.LimitRangeList{ + Items: []api.LimitRange{ + { + ObjectMeta: api.ObjectMeta{Name: "foo"}, + }, + }, + } + c := &testClient{ + Request: testRequest{ + Method: "GET", + Path: buildResourcePath(ns, "/limitRanges"), + Query: buildQueryValues(ns, nil), + Body: nil, + }, + Response: Response{StatusCode: 200, Body: limitRangeList}, + } + response, err := c.Setup().LimitRanges(ns).List(labels.Everything()) + c.Validate(t, response, err) +} + +func TestLimitRangeUpdate(t *testing.T) { + ns := api.NamespaceDefault + limitRange := &api.LimitRange{ + ObjectMeta: api.ObjectMeta{ + Name: "abc", + ResourceVersion: "1", + }, + Spec: api.LimitRangeSpec{ + Limits: []api.LimitRangeItem{ + { + Type: api.LimitTypePod, + Max: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100"), + api.ResourceMemory: resource.MustParse("10000"), + }, + Min: api.ResourceList{ + api.ResourceCPU: resource.MustParse("0"), + api.ResourceMemory: resource.MustParse("100"), + }, + }, + }, + }, + } + c := &testClient{ + Request: testRequest{Method: "PUT", Path: buildResourcePath(ns, "/limitRanges/abc"), Query: buildQueryValues(ns, nil)}, + Response: Response{StatusCode: 200, Body: limitRange}, + } + response, err := c.Setup().LimitRanges(ns).Update(limitRange) + c.Validate(t, response, err) +} + +func TestInvalidLimitRangeUpdate(t *testing.T) { + ns := api.NamespaceDefault + limitRange := &api.LimitRange{ + ObjectMeta: api.ObjectMeta{ + Name: "abc", + }, + Spec: api.LimitRangeSpec{ + Limits: []api.LimitRangeItem{ + { + Type: api.LimitTypePod, + Max: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100"), + api.ResourceMemory: resource.MustParse("10000"), + }, + Min: api.ResourceList{ + api.ResourceCPU: resource.MustParse("0"), + api.ResourceMemory: resource.MustParse("100"), + }, + }, + }, + }, + } + c := &testClient{ + Request: testRequest{Method: "PUT", Path: buildResourcePath(ns, "/limitRanges/abc"), Query: buildQueryValues(ns, nil)}, + Response: Response{StatusCode: 200, Body: limitRange}, + } + _, err := c.Setup().LimitRanges(ns).Update(limitRange) + if err == nil { + t.Errorf("Expected an error due to missing ResourceVersion") + } +} + +func TestLimitRangeDelete(t *testing.T) { + ns := api.NamespaceDefault + c := &testClient{ + Request: testRequest{Method: "DELETE", Path: buildResourcePath(ns, "/limitRanges/foo"), Query: buildQueryValues(ns, nil)}, + Response: Response{StatusCode: 200}, + } + err := c.Setup().LimitRanges(ns).Delete("foo") + c.Validate(t, nil, err) +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/minions.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/minions.go index 2ed08688723c..fb4c20cd9989 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/minions.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/minions.go @@ -18,6 +18,7 @@ package client import ( "errors" + "fmt" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" ) @@ -31,6 +32,7 @@ type NodeInterface interface { Create(minion *api.Node) (*api.Node, error) List() (*api.NodeList, error) Delete(name string) error + Update(*api.Node) (*api.Node, error) } // nodes implements NodesInterface @@ -44,6 +46,7 @@ func newNodes(c *Client) *nodes { return &nodes{c} } +// resourceName returns node's URL resource name based on resource version. func (c *nodes) resourceName() string { if preV1Beta3(c.r.APIVersion()) { return "minions" @@ -51,7 +54,7 @@ func (c *nodes) resourceName() string { return "nodes" } -// Create creates a new minion. +// Create creates a new node. func (c *nodes) Create(minion *api.Node) (*api.Node, error) { result := &api.Node{} err := c.r.Post().Resource(c.resourceName()).Body(minion).Do().Into(result) @@ -65,7 +68,7 @@ func (c *nodes) List() (*api.NodeList, error) { return result, err } -// Get gets an existing minion +// Get gets an existing node. func (c *nodes) Get(name string) (*api.Node, error) { if len(name) == 0 { return nil, errors.New("name is required parameter to Get") @@ -76,7 +79,18 @@ func (c *nodes) Get(name string) (*api.Node, error) { return result, err } -// Delete deletes an existing minion. +// Delete deletes an existing node. func (c *nodes) Delete(name string) error { return c.r.Delete().Resource(c.resourceName()).Name(name).Do().Error() } + +// Update updates an existing node. +func (c *nodes) Update(minion *api.Node) (*api.Node, error) { + result := &api.Node{} + if len(minion.ResourceVersion) == 0 { + err := fmt.Errorf("invalid update object, missing resource version: %v", minion) + return nil, err + } + err := c.r.Put().Resource(c.resourceName()).Name(minion.Name).Body(minion).Do().Into(result) + return result, err +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/request.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/request.go index ca0fb9aadc97..e9b5b50f72cc 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/request.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/request.go @@ -35,17 +35,12 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch" watchjson "github.com/GoogleCloudPlatform/kubernetes/pkg/watch/json" + "github.com/golang/glog" ) // specialParams lists parameters that are handled specially and which users of Request // are therefore not allowed to set manually. -var specialParams = util.NewStringSet("sync", "timeout") - -// PollFunc is called when a server operation returns 202 accepted. The name of the -// operation is extracted from the response and passed to this function. Return a -// request to retrieve the result of the operation, or false for the second argument -// if polling should end. -type PollFunc func(name string) (*Request, bool) +var specialParams = util.NewStringSet("timeout") // HTTPClient is an interface for testing a request object. type HTTPClient interface { @@ -85,10 +80,6 @@ type Request struct { baseURL *url.URL codec runtime.Codec - // optional, will be invoked if the server returns a 202 to decide - // whether to poll. - poller PollFunc - // If true, add "?namespace=" as a query parameter, if false put ns/ in path // Query parameter is considered legacy behavior namespaceInQuery bool @@ -107,7 +98,6 @@ type Request struct { resource string resourceName string selector labels.Selector - sync bool timeout time.Duration // output @@ -177,15 +167,6 @@ func (r *Request) Name(resourceName string) *Request { return r } -// Sync sets sync/async call status by setting the "sync" parameter to "true"/"false". -func (r *Request) Sync(sync bool) *Request { - if r.err != nil { - return r - } - r.sync = sync - return r -} - // Namespace applies the namespace scope to a request (/[ns//]) func (r *Request) Namespace(namespace string) *Request { if r.err != nil { @@ -270,7 +251,7 @@ func (r *Request) setParam(paramName, value string) *Request { } // Timeout makes the request use the given duration as a timeout. Sets the "timeout" -// parameter. Ignored if sync=false. +// parameter. func (r *Request) Timeout(d time.Duration) *Request { if r.err != nil { return r @@ -314,22 +295,6 @@ func (r *Request) Body(obj interface{}) *Request { return r } -// NoPoll indicates a server "working" response should be returned as an error -func (r *Request) NoPoll() *Request { - return r.Poller(nil) -} - -// Poller indicates this request should use the specified poll function to determine whether -// a server "working" response should be retried. The poller is responsible for waiting or -// outputting messages to the client. -func (r *Request) Poller(poller PollFunc) *Request { - if r.err != nil { - return r - } - r.poller = poller - return r -} - func (r *Request) finalURL() string { p := r.path if r.namespaceSet && !r.namespaceInQuery && len(r.namespace) > 0 { @@ -359,13 +324,9 @@ func (r *Request) finalURL() string { query.Add("namespace", r.namespace) } - // sync and timeout are handled specially here, to allow setting them - // in any order. - if r.sync { - query.Add("sync", "true") - if r.timeout != 0 { - query.Add("timeout", r.timeout.String()) - } + // timeout is handled specially here. + if r.timeout != 0 { + query.Add("timeout", r.timeout.String()) } finalURL.RawQuery = query.Encode() return finalURL.String() @@ -443,7 +404,7 @@ func (r *Request) Stream() (io.ReadCloser, error) { } // Do formats and executes the request. Returns a Result object for easy response -// processing. Handles polling the server in the event a continuation was sent. +// processing. // // Error type: // * If the request can't be constructed, or an error happened earlier while building its @@ -457,6 +418,10 @@ func (r *Request) Do() Result { client = http.DefaultClient } + // Right now we make about ten retry attempts if we get a Retry-After response. + // TODO: Change to a timeout based approach. + retries := 0 + for { if r.err != nil { return Result{err: &RequestConstructionError{r.err}} @@ -473,36 +438,25 @@ func (r *Request) Do() Result { } respBody, created, err := r.transformResponse(resp, req) - if poll, ok := r.shouldPoll(err); ok { - r = poll - continue - } + // Check to see if we got a 429 Too Many Requests response code. + if resp.StatusCode == errors.StatusTooManyRequests { + if retries < 10 { + retries++ + if waitFor := resp.Header.Get("Retry-After"); waitFor != "" { + delay, err := strconv.Atoi(waitFor) + if err == nil { + glog.V(4).Infof("Got a Retry-After %s response for attempt %d to %v", waitFor, retries, r.finalURL()) + time.Sleep(time.Duration(delay) * time.Second) + continue + } + } + } + } return Result{respBody, created, err, r.codec} } } -// shouldPoll checks the server error for an incomplete operation -// and if found returns a request that would check the response. -// If no polling is necessary or possible, it will return false. -func (r *Request) shouldPoll(err error) (*Request, bool) { - if err == nil || r.poller == nil { - return nil, false - } - apistatus, ok := err.(APIStatus) - if !ok { - return nil, false - } - status := apistatus.Status() - if status.Status != api.StatusWorking { - return nil, false - } - if status.Details == nil || len(status.Details.ID) == 0 { - return nil, false - } - return r.poller(status.Details.ID) -} - // transformResponse converts an API response into a structured API object. func (r *Request) transformResponse(resp *http.Response, req *http.Request) ([]byte, bool, error) { defer resp.Body.Close() diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/request_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/request_test.go index 3f96e02d4a1b..1439625d0eea 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/request_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/request_test.go @@ -44,10 +44,6 @@ import ( watchjson "github.com/GoogleCloudPlatform/kubernetes/pkg/watch/json" ) -func skipPolling(name string) (*Request, bool) { - return nil, false -} - func TestRequestWithErrorWontChange(t *testing.T) { original := Request{err: errors.New("test")} r := original @@ -61,11 +57,8 @@ func TestRequestWithErrorWontChange(t *testing.T) { Namespace("new"). Resource("foos"). Name("bars"). - NoPoll(). Body("foo"). - Poller(skipPolling). - Timeout(time.Millisecond). - Sync(true) + Timeout(time.Millisecond) if changed != &r { t.Errorf("returned request should point to the same object") } @@ -501,7 +494,7 @@ func TestDoRequestNewWay(t *testing.T) { } else if !reflect.DeepEqual(obj, expectedObj) { t.Errorf("Expected: %#v, got %#v", expectedObj, obj) } - fakeHandler.ValidateRequest(t, "/api/v1beta2/foo/bar/baz?labels=name%3Dfoo", "POST", &reqBody) + fakeHandler.ValidateRequest(t, "/api/v1beta2/foo/bar/baz?labels=name%3Dfoo&timeout=1s", "POST", &reqBody) if fakeHandler.RequestReceived.Header["Authorization"] == nil { t.Errorf("Request is missing authorization header: %#v", *fakeHandler.RequestReceived) } @@ -524,7 +517,6 @@ func TestDoRequestNewWayReader(t *testing.T) { Name("baz"). Prefix("foo"). SelectorParam("labels", labels.Set{"name": "foo"}.AsSelector()). - Sync(true). Timeout(time.Second). Body(bytes.NewBuffer(reqBodyExpected)). Do().Get() @@ -538,7 +530,7 @@ func TestDoRequestNewWayReader(t *testing.T) { t.Errorf("Expected: %#v, got %#v", expectedObj, obj) } tmpStr := string(reqBodyExpected) - fakeHandler.ValidateRequest(t, "/api/v1beta1/foo/bar/baz?labels=name%3Dfoo&sync=true&timeout=1s", "POST", &tmpStr) + fakeHandler.ValidateRequest(t, "/api/v1beta1/foo/bar/baz?labels=name%3Dfoo&timeout=1s", "POST", &tmpStr) if fakeHandler.RequestReceived.Header["Authorization"] == nil { t.Errorf("Request is missing authorization header: %#v", *fakeHandler.RequestReceived) } @@ -574,7 +566,7 @@ func TestDoRequestNewWayObj(t *testing.T) { t.Errorf("Expected: %#v, got %#v", expectedObj, obj) } tmpStr := string(reqBodyExpected) - fakeHandler.ValidateRequest(t, "/api/v1beta2/foo/bar/baz?labels=name%3Dfoo", "POST", &tmpStr) + fakeHandler.ValidateRequest(t, "/api/v1beta2/foo/bar/baz?labels=name%3Dfoo&timeout=1s", "POST", &tmpStr) if fakeHandler.RequestReceived.Header["Authorization"] == nil { t.Errorf("Request is missing authorization header: %#v", *fakeHandler.RequestReceived) } @@ -626,7 +618,7 @@ func TestDoRequestNewWayFile(t *testing.T) { t.Errorf("expected object was not created") } tmpStr := string(reqBodyExpected) - fakeHandler.ValidateRequest(t, "/api/v1beta1/foo/bar/baz?labels=name%3Dfoo", "POST", &tmpStr) + fakeHandler.ValidateRequest(t, "/api/v1beta1/foo/bar/baz?labels=name%3Dfoo&timeout=1s", "POST", &tmpStr) if fakeHandler.RequestReceived.Header["Authorization"] == nil { t.Errorf("Request is missing authorization header: %#v", *fakeHandler.RequestReceived) } @@ -669,7 +661,7 @@ func TestWasCreated(t *testing.T) { } tmpStr := string(reqBodyExpected) - fakeHandler.ValidateRequest(t, "/api/v1beta1/foo/bar/baz?labels=name%3Dfoo", "PUT", &tmpStr) + fakeHandler.ValidateRequest(t, "/api/v1beta1/foo/bar/baz?labels=name%3Dfoo&timeout=1s", "PUT", &tmpStr) if fakeHandler.RequestReceived.Header["Authorization"] == nil { t.Errorf("Request is missing authorization header: %#v", *fakeHandler.RequestReceived) } @@ -700,22 +692,6 @@ func TestAbsPath(t *testing.T) { } } -func TestSync(t *testing.T) { - c := NewOrDie(&Config{}) - r := c.Get() - if r.sync { - t.Errorf("sync has wrong default") - } - r.Sync(false) - if r.sync { - t.Errorf("'Sync' doesn't work") - } - r.Sync(true) - if !r.sync { - t.Errorf("'Sync' doesn't work") - } -} - func TestUintParam(t *testing.T) { table := []struct { name string @@ -742,7 +718,6 @@ func TestUnacceptableParamNames(t *testing.T) { testVal string expectSuccess bool }{ - {"sync", "foo", false}, {"timeout", "42", false}, } @@ -787,90 +762,6 @@ func TestBody(t *testing.T) { } } -func TestSetPoller(t *testing.T) { - c := NewOrDie(&Config{}) - r := c.Get() - if c.PollPeriod == 0 { - t.Errorf("polling should be on by default") - } - if r.poller == nil { - t.Errorf("polling should be on by default") - } - r.NoPoll() - if r.poller != nil { - t.Errorf("'NoPoll' doesn't work") - } -} - -func TestPolling(t *testing.T) { - objects := []runtime.Object{ - &api.Status{Status: api.StatusWorking, Details: &api.StatusDetails{ID: "1234"}}, - &api.Status{Status: api.StatusWorking, Details: &api.StatusDetails{ID: "1234"}}, - &api.Status{Status: api.StatusWorking, Details: &api.StatusDetails{ID: "1234"}}, - &api.Status{Status: api.StatusWorking, Details: &api.StatusDetails{ID: "1234"}}, - &api.Status{Status: api.StatusSuccess}, - } - - callNumber := 0 - testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if callNumber == 0 { - if r.URL.Path != "/api/v1beta1/" { - t.Fatalf("unexpected request URL path %s", r.URL.Path) - } - } else { - if r.URL.Path != "/api/v1beta1/operations/1234" { - t.Fatalf("unexpected request URL path %s", r.URL.Path) - } - } - t.Logf("About to write %d", callNumber) - data, err := v1beta1.Codec.Encode(objects[callNumber]) - if err != nil { - t.Errorf("Unexpected encode error") - } - callNumber++ - w.Write(data) - })) - - c := NewOrDie(&Config{Host: testServer.URL, Version: "v1beta1", Username: "user", Password: "pass"}) - c.PollPeriod = 1 * time.Millisecond - trials := []func(){ - func() { - // Check that we do indeed poll when asked to. - obj, err := c.Get().Do().Get() - if err != nil { - t.Errorf("Unexpected error: %v %#v", err, err) - return - } - if s, ok := obj.(*api.Status); !ok || s.Status != api.StatusSuccess { - t.Errorf("Unexpected return object: %#v", obj) - return - } - if callNumber != len(objects) { - t.Errorf("Unexpected number of calls: %v", callNumber) - } - }, - func() { - // Check that we don't poll when asked not to. - obj, err := c.Get().NoPoll().Do().Get() - if err == nil { - t.Errorf("Unexpected non error: %v", obj) - return - } - if se, ok := err.(APIStatus); !ok || se.Status().Status != api.StatusWorking { - t.Errorf("Unexpected kind of error: %#v", err) - return - } - if callNumber != 1 { - t.Errorf("Unexpected number of calls: %v", callNumber) - } - }, - } - for _, f := range trials { - callNumber = 0 - f() - } -} - func authFromReq(r *http.Request) (*Config, bool) { auth, ok := r.Header["Authorization"] if !ok { diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/resource_quota_usages.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/resource_quota_usages.go new file mode 100644 index 000000000000..1ba2c5e5e827 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/resource_quota_usages.go @@ -0,0 +1,57 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 client + +import ( + "fmt" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" +) + +// ResourceQuotaUsagesNamespacer has methods to work with ResourceQuotaUsage resources in a namespace +type ResourceQuotaUsagesNamespacer interface { + ResourceQuotaUsages(namespace string) ResourceQuotaUsageInterface +} + +// ResourceQuotaUsageInterface has methods to work with ResourceQuotaUsage resources. +type ResourceQuotaUsageInterface interface { + Create(resourceQuotaUsage *api.ResourceQuotaUsage) error +} + +// resourceQuotaUsages implements ResourceQuotaUsagesNamespacer interface +type resourceQuotaUsages struct { + r *Client + ns string +} + +// newResourceQuotaUsages returns a resourceQuotaUsages +func newResourceQuotaUsages(c *Client, namespace string) *resourceQuotaUsages { + return &resourceQuotaUsages{ + r: c, + ns: namespace, + } +} + +// Create takes the representation of a resourceQuotaUsage. Returns an error if the usage was not applied +func (c *resourceQuotaUsages) Create(resourceQuotaUsage *api.ResourceQuotaUsage) (err error) { + if len(resourceQuotaUsage.ResourceVersion) == 0 { + err = fmt.Errorf("invalid update object, missing resource version: %v", resourceQuotaUsage) + return + } + err = c.r.Post().Namespace(c.ns).Resource("resourceQuotaUsages").Body(resourceQuotaUsage).Do().Error() + return +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/resource_quota_usages_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/resource_quota_usages_test.go new file mode 100644 index 000000000000..eb2c65f1bcb3 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/resource_quota_usages_test.go @@ -0,0 +1,93 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 client + +import ( + "testing" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource" +) + +func TestResourceQuotaUsageCreate(t *testing.T) { + ns := api.NamespaceDefault + resourceQuotaUsage := &api.ResourceQuotaUsage{ + ObjectMeta: api.ObjectMeta{ + Name: "abc", + Namespace: "foo", + ResourceVersion: "1", + }, + Status: api.ResourceQuotaStatus{ + Hard: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100"), + api.ResourceMemory: resource.MustParse("10000"), + api.ResourcePods: resource.MustParse("10"), + api.ResourceServices: resource.MustParse("10"), + api.ResourceReplicationControllers: resource.MustParse("10"), + api.ResourceQuotas: resource.MustParse("10"), + }, + }, + } + c := &testClient{ + Request: testRequest{ + Method: "POST", + Path: buildResourcePath(ns, "/resourceQuotaUsages"), + Query: buildQueryValues(ns, nil), + Body: resourceQuotaUsage, + }, + Response: Response{StatusCode: 200, Body: resourceQuotaUsage}, + } + + err := c.Setup().ResourceQuotaUsages(ns).Create(resourceQuotaUsage) + if err != nil { + t.Errorf("Unexpected error %v", err) + } +} + +func TestInvalidResourceQuotaUsageCreate(t *testing.T) { + ns := api.NamespaceDefault + resourceQuotaUsage := &api.ResourceQuotaUsage{ + ObjectMeta: api.ObjectMeta{ + Name: "abc", + Namespace: "foo", + }, + Status: api.ResourceQuotaStatus{ + Hard: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100"), + api.ResourceMemory: resource.MustParse("10000"), + api.ResourcePods: resource.MustParse("10"), + api.ResourceServices: resource.MustParse("10"), + api.ResourceReplicationControllers: resource.MustParse("10"), + api.ResourceQuotas: resource.MustParse("10"), + }, + }, + } + c := &testClient{ + Request: testRequest{ + Method: "POST", + Path: buildResourcePath(ns, "/resourceQuotaUsages"), + Query: buildQueryValues(ns, nil), + Body: resourceQuotaUsage, + }, + Response: Response{StatusCode: 200, Body: resourceQuotaUsage}, + } + + err := c.Setup().ResourceQuotaUsages(ns).Create(resourceQuotaUsage) + if err == nil { + t.Errorf("Expected error due to missing ResourceVersion") + } +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/resource_quotas.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/resource_quotas.go new file mode 100644 index 000000000000..d0d51ea800a1 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/resource_quotas.go @@ -0,0 +1,94 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 client + +import ( + "errors" + "fmt" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" +) + +// ResourceQuotasNamespacer has methods to work with ResourceQuota resources in a namespace +type ResourceQuotasNamespacer interface { + ResourceQuotas(namespace string) ResourceQuotaInterface +} + +// ResourceQuotaInterface has methods to work with ResourceQuota resources. +type ResourceQuotaInterface interface { + List(selector labels.Selector) (*api.ResourceQuotaList, error) + Get(name string) (*api.ResourceQuota, error) + Delete(name string) error + Create(resourceQuota *api.ResourceQuota) (*api.ResourceQuota, error) + Update(resourceQuota *api.ResourceQuota) (*api.ResourceQuota, error) +} + +// resourceQuotas implements ResourceQuotasNamespacer interface +type resourceQuotas struct { + r *Client + ns string +} + +// newResourceQuotas returns a resourceQuotas +func newResourceQuotas(c *Client, namespace string) *resourceQuotas { + return &resourceQuotas{ + r: c, + ns: namespace, + } +} + +// List takes a selector, and returns the list of resourceQuotas that match that selector. +func (c *resourceQuotas) List(selector labels.Selector) (result *api.ResourceQuotaList, err error) { + result = &api.ResourceQuotaList{} + err = c.r.Get().Namespace(c.ns).Resource("resourceQuotas").SelectorParam("labels", selector).Do().Into(result) + return +} + +// Get takes the name of the resourceQuota, and returns the corresponding ResourceQuota object, and an error if it occurs +func (c *resourceQuotas) Get(name string) (result *api.ResourceQuota, err error) { + if len(name) == 0 { + return nil, errors.New("name is required parameter to Get") + } + + result = &api.ResourceQuota{} + err = c.r.Get().Namespace(c.ns).Resource("resourceQuotas").Name(name).Do().Into(result) + return +} + +// Delete takes the name of the resourceQuota, and returns an error if one occurs +func (c *resourceQuotas) Delete(name string) error { + return c.r.Delete().Namespace(c.ns).Resource("resourceQuotas").Name(name).Do().Error() +} + +// Create takes the representation of a resourceQuota. Returns the server's representation of the resourceQuota, and an error, if it occurs. +func (c *resourceQuotas) Create(resourceQuota *api.ResourceQuota) (result *api.ResourceQuota, err error) { + result = &api.ResourceQuota{} + err = c.r.Post().Namespace(c.ns).Resource("resourceQuotas").Body(resourceQuota).Do().Into(result) + return +} + +// Update takes the representation of a resourceQuota to update. Returns the server's representation of the resourceQuota, and an error, if it occurs. +func (c *resourceQuotas) Update(resourceQuota *api.ResourceQuota) (result *api.ResourceQuota, err error) { + result = &api.ResourceQuota{} + if len(resourceQuota.ResourceVersion) == 0 { + err = fmt.Errorf("invalid update object, missing resource version: %v", resourceQuota) + return + } + err = c.r.Put().Namespace(c.ns).Resource("resourceQuotas").Name(resourceQuota.Name).Body(resourceQuota).Do().Into(result) + return +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/resource_quotas_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/resource_quotas_test.go new file mode 100644 index 000000000000..22eee5dadabf --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/resource_quotas_test.go @@ -0,0 +1,177 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 client + +import ( + "testing" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource" + "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" +) + +func TestResourceQuotaCreate(t *testing.T) { + ns := api.NamespaceDefault + resourceQuota := &api.ResourceQuota{ + ObjectMeta: api.ObjectMeta{ + Name: "abc", + Namespace: "foo", + }, + Spec: api.ResourceQuotaSpec{ + Hard: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100"), + api.ResourceMemory: resource.MustParse("10000"), + api.ResourcePods: resource.MustParse("10"), + api.ResourceServices: resource.MustParse("10"), + api.ResourceReplicationControllers: resource.MustParse("10"), + api.ResourceQuotas: resource.MustParse("10"), + }, + }, + } + c := &testClient{ + Request: testRequest{ + Method: "POST", + Path: buildResourcePath(ns, "/resourceQuotas"), + Query: buildQueryValues(ns, nil), + Body: resourceQuota, + }, + Response: Response{StatusCode: 200, Body: resourceQuota}, + } + + response, err := c.Setup().ResourceQuotas(ns).Create(resourceQuota) + c.Validate(t, response, err) +} + +func TestResourceQuotaGet(t *testing.T) { + ns := api.NamespaceDefault + resourceQuota := &api.ResourceQuota{ + ObjectMeta: api.ObjectMeta{ + Name: "abc", + Namespace: "foo", + }, + Spec: api.ResourceQuotaSpec{ + Hard: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100"), + api.ResourceMemory: resource.MustParse("10000"), + api.ResourcePods: resource.MustParse("10"), + api.ResourceServices: resource.MustParse("10"), + api.ResourceReplicationControllers: resource.MustParse("10"), + api.ResourceQuotas: resource.MustParse("10"), + }, + }, + } + c := &testClient{ + Request: testRequest{ + Method: "GET", + Path: buildResourcePath(ns, "/resourceQuotas/abc"), + Query: buildQueryValues(ns, nil), + Body: nil, + }, + Response: Response{StatusCode: 200, Body: resourceQuota}, + } + + response, err := c.Setup().ResourceQuotas(ns).Get("abc") + c.Validate(t, response, err) +} + +func TestResourceQuotaList(t *testing.T) { + ns := api.NamespaceDefault + + resourceQuotaList := &api.ResourceQuotaList{ + Items: []api.ResourceQuota{ + { + ObjectMeta: api.ObjectMeta{Name: "foo"}, + }, + }, + } + c := &testClient{ + Request: testRequest{ + Method: "GET", + Path: buildResourcePath(ns, "/resourceQuotas"), + Query: buildQueryValues(ns, nil), + Body: nil, + }, + Response: Response{StatusCode: 200, Body: resourceQuotaList}, + } + response, err := c.Setup().ResourceQuotas(ns).List(labels.Everything()) + c.Validate(t, response, err) +} + +func TestResourceQuotaUpdate(t *testing.T) { + ns := api.NamespaceDefault + resourceQuota := &api.ResourceQuota{ + ObjectMeta: api.ObjectMeta{ + Name: "abc", + Namespace: "foo", + ResourceVersion: "1", + }, + Spec: api.ResourceQuotaSpec{ + Hard: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100"), + api.ResourceMemory: resource.MustParse("10000"), + api.ResourcePods: resource.MustParse("10"), + api.ResourceServices: resource.MustParse("10"), + api.ResourceReplicationControllers: resource.MustParse("10"), + api.ResourceQuotas: resource.MustParse("10"), + }, + }, + } + c := &testClient{ + Request: testRequest{Method: "PUT", Path: buildResourcePath(ns, "/resourceQuotas/abc"), Query: buildQueryValues(ns, nil)}, + Response: Response{StatusCode: 200, Body: resourceQuota}, + } + response, err := c.Setup().ResourceQuotas(ns).Update(resourceQuota) + c.Validate(t, response, err) +} + +func TestInvalidResourceQuotaUpdate(t *testing.T) { + ns := api.NamespaceDefault + resourceQuota := &api.ResourceQuota{ + ObjectMeta: api.ObjectMeta{ + Name: "abc", + Namespace: "foo", + }, + Spec: api.ResourceQuotaSpec{ + Hard: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100"), + api.ResourceMemory: resource.MustParse("10000"), + api.ResourcePods: resource.MustParse("10"), + api.ResourceServices: resource.MustParse("10"), + api.ResourceReplicationControllers: resource.MustParse("10"), + api.ResourceQuotas: resource.MustParse("10"), + }, + }, + } + c := &testClient{ + Request: testRequest{Method: "PUT", Path: buildResourcePath(ns, "/resourceQuotas/abc"), Query: buildQueryValues(ns, nil)}, + Response: Response{StatusCode: 200, Body: resourceQuota}, + } + _, err := c.Setup().ResourceQuotas(ns).Update(resourceQuota) + if err == nil { + t.Errorf("Expected an error due to missing ResourceVersion") + } +} + +func TestResourceQuotaDelete(t *testing.T) { + ns := api.NamespaceDefault + c := &testClient{ + Request: testRequest{Method: "DELETE", Path: buildResourcePath(ns, "/resourceQuotas/foo"), Query: buildQueryValues(ns, nil)}, + Response: Response{StatusCode: 200}, + } + err := c.Setup().ResourceQuotas(ns).Delete("foo") + c.Validate(t, nil, err) +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/restclient.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/restclient.go index 1cda59391ab0..a481e83fabd8 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/restclient.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/restclient.go @@ -22,8 +22,6 @@ import ( "time" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" - - "github.com/golang/glog" ) // RESTClient imposes common Kubernetes API conventions on a set of resource paths. @@ -51,13 +49,7 @@ type RESTClient struct { // used. Client HTTPClient - // Set the poll behavior of this client. If not set the DefaultPoll method will - // be called. - Poller PollFunc - - Sync bool - PollPeriod time.Duration - Timeout time.Duration + Timeout time.Duration } // NewRESTClient creates a new RESTClient. This client performs generic REST functions @@ -79,12 +71,6 @@ func NewRESTClient(baseURL *url.URL, apiVersion string, c runtime.Codec, legacyB Codec: c, LegacyBehavior: legacyBehavior, - - // Make asynchronous requests by default - Sync: false, - - // Poll frequently when asynchronous requests are provided - PollPeriod: time.Second * 2, } } @@ -106,11 +92,7 @@ func (c *RESTClient) Verb(verb string) *Request { // if c.Client != nil { // timeout = c.Client.Timeout // } - poller := c.Poller - if poller == nil { - poller = c.DefaultPoll - } - return NewRequest(c.Client, verb, c.baseURL, c.Codec, c.LegacyBehavior, c.LegacyBehavior).Poller(poller).Sync(c.Sync).Timeout(c.Timeout) + return NewRequest(c.Client, verb, c.baseURL, c.Codec, c.LegacyBehavior, c.LegacyBehavior).Timeout(c.Timeout) } // Post begins a POST request. Short for c.Verb("POST"). @@ -133,22 +115,6 @@ func (c *RESTClient) Delete() *Request { return c.Verb("DELETE") } -// PollFor makes a request to do a single poll of the completion of the given operation. -func (c *RESTClient) Operation(name string) *Request { - return c.Get().Resource("operations").Name(name).Sync(false).NoPoll() -} - -// DefaultPoll performs a polling action based on the PollPeriod set on the Client. -func (c *RESTClient) DefaultPoll(name string) (*Request, bool) { - if c.PollPeriod == 0 { - return nil, false - } - glog.Infof("Waiting for completion of operation %s", name) - time.Sleep(c.PollPeriod) - // Make a poll request - return c.Operation(name).Poller(c.DefaultPoll), true -} - // APIVersion returns the APIVersion this RESTClient is expected to use. func (c *RESTClient) APIVersion() string { return c.apiVersion diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/restclient_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/restclient_test.go index 073e1c4bb8cf..7f50bd8d3715 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/restclient_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/restclient_test.go @@ -157,10 +157,10 @@ func TestValidatesHostParameter(t *testing.T) { } func TestDoRequestBearer(t *testing.T) { - status := &api.Status{Status: api.StatusWorking} + status := &api.Status{Status: api.StatusFailure} expectedBody, _ := latest.Codec.Encode(status) fakeHandler := util.FakeHandler{ - StatusCode: 202, + StatusCode: 400, ResponseBody: string(expectedBody), T: t, } @@ -187,11 +187,11 @@ func TestDoRequestBearer(t *testing.T) { } } -func TestDoRequestAccepted(t *testing.T) { - status := &api.Status{Status: api.StatusWorking} +func TestDoRequestWithoutPassword(t *testing.T) { + status := &api.Status{Status: api.StatusFailure} expectedBody, _ := latest.Codec.Encode(status) fakeHandler := util.FakeHandler{ - StatusCode: 202, + StatusCode: 400, ResponseBody: string(expectedBody), T: t, } @@ -228,11 +228,11 @@ func TestDoRequestAccepted(t *testing.T) { fakeHandler.ValidateRequest(t, "/"+testapi.Version()+"/test", "GET", nil) } -func TestDoRequestAcceptedSuccess(t *testing.T) { +func TestDoRequestSuccess(t *testing.T) { status := &api.Status{Status: api.StatusSuccess} expectedBody, _ := latest.Codec.Encode(status) fakeHandler := util.FakeHandler{ - StatusCode: 202, + StatusCode: 200, ResponseBody: string(expectedBody), T: t, } @@ -339,10 +339,3 @@ func TestDoRequestCreated(t *testing.T) { } fakeHandler.ValidateRequest(t, "/"+testapi.Version()+"/test", "GET", nil) } - -func TestDefaultPoll(t *testing.T) { - c := &RESTClient{PollPeriod: 0} - if req, ok := c.DefaultPoll("test"); req != nil || ok { - t.Errorf("expected nil request and not poll") - } -} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/controller/nodecontroller.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/controller/nodecontroller.go index de2a619de81e..25fb005ff9d0 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/controller/nodecontroller.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/controller/nodecontroller.go @@ -17,97 +17,125 @@ limitations under the License. package controller import ( + "errors" "fmt" "net" + "reflect" + "sync" "time" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider" + "github.com/GoogleCloudPlatform/kubernetes/pkg/probe" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/golang/glog" ) +var ( + ErrRegistration = errors.New("unable to register all nodes.") +) + type NodeController struct { cloud cloudprovider.Interface matchRE string staticResources *api.NodeResources nodes []string kubeClient client.Interface + kubeletClient client.KubeletHealthChecker } // NewNodeController returns a new node controller to sync instances from cloudprovider. +// TODO: NodeController health checker should be a separate package other than +// kubeletclient, node health check != kubelet health check. func NewNodeController( cloud cloudprovider.Interface, matchRE string, nodes []string, staticResources *api.NodeResources, - kubeClient client.Interface) *NodeController { + kubeClient client.Interface, + kubeletClient client.KubeletHealthChecker) *NodeController { return &NodeController{ cloud: cloud, matchRE: matchRE, nodes: nodes, staticResources: staticResources, kubeClient: kubeClient, + kubeletClient: kubeletClient, } } -// Run starts syncing instances from cloudprovider periodically, or create initial node list. -func (s *NodeController) Run(period time.Duration) { - if s.cloud != nil && len(s.matchRE) > 0 { +// Run creates initial node list and start syncing instances from cloudprovider if any. +// It also starts syncing cluster node status. +func (s *NodeController) Run(period time.Duration, retryCount int) { + // Register intial set of nodes with their status set. + var nodes *api.NodeList + var err error + if s.isRunningCloudProvider() { + nodes, err = s.CloudNodes() + if err != nil { + glog.Errorf("Error loading initial node from cloudprovider: %v", err) + } + } else { + nodes, err = s.StaticNodes() + if err != nil { + glog.Errorf("Error loading initial static nodes") + } + } + nodes = s.DoChecks(nodes) + if err := s.RegisterNodes(nodes, retryCount, period); err != nil { + glog.Errorf("Error registrying node list: %+v", nodes) + } + + // Start syncing node list from cloudprovider. + if s.isRunningCloudProvider() { go util.Forever(func() { - if err := s.SyncCloud(); err != nil { + if err = s.SyncCloud(); err != nil { glog.Errorf("Error syncing cloud: %v", err) } }, period) - } else { - go s.SyncStatic(period) } + + // Start syncing node status. + go util.Forever(func() { + if err = s.SyncNodeStatus(); err != nil { + glog.Errorf("Error syncing status: %v", err) + } + }, period) } -// SyncStatic registers list of machines from command line flag. It returns after successful -// registration of all machines. -func (s *NodeController) SyncStatic(period time.Duration) error { +// RegisterNodes registers the given list of nodes, it keeps retrying for `retryCount` times. +func (s *NodeController) RegisterNodes(nodes *api.NodeList, retryCount int, retryInterval time.Duration) error { registered := util.NewStringSet() - for { - for _, nodeID := range s.nodes { - if registered.Has(nodeID) { + for i := 0; i < retryCount; i++ { + for _, node := range nodes.Items { + if registered.Has(node.Name) { continue } - node := &api.Node{ - ObjectMeta: api.ObjectMeta{Name: nodeID}, - Spec: api.NodeSpec{ - Capacity: s.staticResources.Capacity, - }, - } - addr := net.ParseIP(nodeID) - if addr != nil { - node.Status.HostIP = nodeID + _, err := s.kubeClient.Nodes().Create(&node) + if err == nil { + registered.Insert(node.Name) + glog.Infof("Registered node in registry: %s", node.Name) } else { - addrs, err := net.LookupIP(nodeID) - if err != nil { - glog.Errorf("Can't get ip address of node %v", nodeID) - } else if len(addrs) == 0 { - glog.Errorf("No ip address for node %v", nodeID) - } else { - node.Status.HostIP = addrs[0].String() - } + glog.Errorf("Error registrying node %s, retrying: %s", node.Name, err) } - _, err := s.kubeClient.Nodes().Create(node) - if err == nil { - registered.Insert(nodeID) + if registered.Len() == len(nodes.Items) { + glog.Infof("Successfully Registered all nodes") + return nil } } - if registered.Len() == len(s.nodes) { - return nil - } - time.Sleep(period) + time.Sleep(retryInterval) + } + if registered.Len() != len(nodes.Items) { + return ErrRegistration + } else { + return nil } } -// SyncCloud syncs list of instances from cloudprovider to master etcd registry. +// SyncCloud synchronizes the list of instances from cloudprovider to master server. func (s *NodeController) SyncCloud() error { - matches, err := s.cloudNodes() + matches, err := s.CloudNodes() if err != nil { return err } @@ -120,7 +148,7 @@ func (s *NodeController) SyncCloud() error { nodeMap[node.Name] = &node } - // Create or delete nodes from registry. + // Create nodes which have been created in cloud, but not in kubernetes cluster. for _, node := range matches.Items { if _, ok := nodeMap[node.Name]; !ok { glog.Infof("Create node in registry: %s", node.Name) @@ -132,6 +160,7 @@ func (s *NodeController) SyncCloud() error { delete(nodeMap, node.Name) } + // Delete nodes which have been deleted from cloud, but not from kubernetes cluster. for nodeID := range nodeMap { glog.Infof("Delete node from registry: %s", nodeID) err = s.kubeClient.Nodes().Delete(nodeID) @@ -139,29 +168,121 @@ func (s *NodeController) SyncCloud() error { glog.Errorf("Delete node error: %s", nodeID) } } + return nil } -// cloudNodes constructs and returns api.NodeList from cloudprovider. -func (s *NodeController) cloudNodes() (*api.NodeList, error) { +// SyncNodeStatus synchronizes cluster nodes status to master server. +func (s *NodeController) SyncNodeStatus() error { + nodes, err := s.kubeClient.Nodes().List() + if err != nil { + return err + } + oldNodes := make(map[string]api.Node) + for _, node := range nodes.Items { + oldNodes[node.Name] = node + } + nodes = s.DoChecks(nodes) + for _, node := range nodes.Items { + if reflect.DeepEqual(node, oldNodes[node.Name]) { + glog.V(2).Infof("skip updating node %v", node.Name) + continue + } + glog.V(2).Infof("updating node %v", node.Name) + _, err = s.kubeClient.Nodes().Update(&node) + if err != nil { + glog.Errorf("error updating node %s: %v", node.Name, err) + } + } + return nil +} + +// DoChecks performs health checking for given list of nodes. +func (s *NodeController) DoChecks(nodes *api.NodeList) *api.NodeList { + var wg sync.WaitGroup + wg.Add(len(nodes.Items)) + for i := range nodes.Items { + go func(node *api.Node) { + node.Status.Conditions = s.DoCheck(node) + wg.Done() + }(&nodes.Items[i]) + } + wg.Wait() + return nodes +} + +// DoCheck performs health checking for given node. +func (s *NodeController) DoCheck(node *api.Node) []api.NodeCondition { + var conditions []api.NodeCondition + switch status, err := s.kubeletClient.HealthCheck(node.Name); { + case err != nil: + glog.V(2).Infof("NodeController: node %s health check error: %v", node.Name, err) + conditions = append(conditions, api.NodeCondition{ + Kind: api.NodeReady, + Status: api.ConditionUnknown, + }) + case status == probe.Failure: + conditions = append(conditions, api.NodeCondition{ + Kind: api.NodeReady, + Status: api.ConditionNone, + }) + default: + conditions = append(conditions, api.NodeCondition{ + Kind: api.NodeReady, + Status: api.ConditionFull, + }) + } + glog.V(5).Infof("NodeController: node %q status was %+v", node.Name, conditions) + return conditions +} + +// StaticNodes constructs and returns api.NodeList for static nodes. If error +// occurs, an empty NodeList will be returned with a non-nil error info. +func (s *NodeController) StaticNodes() (*api.NodeList, error) { + result := &api.NodeList{} + for _, nodeID := range s.nodes { + node := api.Node{ + ObjectMeta: api.ObjectMeta{Name: nodeID}, + Spec: api.NodeSpec{Capacity: s.staticResources.Capacity}, + } + addr := net.ParseIP(nodeID) + if addr != nil { + node.Status.HostIP = nodeID + } else { + addrs, err := net.LookupIP(nodeID) + if err != nil { + glog.Errorf("Can't get ip address of node %v", nodeID) + } else if len(addrs) == 0 { + glog.Errorf("No ip address for node %v", nodeID) + } else { + node.Status.HostIP = addrs[0].String() + } + } + result.Items = append(result.Items, node) + } + return result, nil +} + +// CloudNodes constructs and returns api.NodeList from cloudprovider. If error +// occurs, an empty NodeList will be returned with a non-nil error info. +func (s *NodeController) CloudNodes() (*api.NodeList, error) { + result := &api.NodeList{} instances, ok := s.cloud.Instances() if !ok { - return nil, fmt.Errorf("cloud doesn't support instances") + return result, fmt.Errorf("cloud doesn't support instances") } matches, err := instances.List(s.matchRE) if err != nil { - return nil, err - } - result := &api.NodeList{ - Items: make([]api.Node, len(matches)), + return result, err } for i := range matches { - result.Items[i].Name = matches[i] + node := api.Node{} + node.Name = matches[i] hostIP, err := instances.IPAddress(matches[i]) if err != nil { glog.Errorf("error getting instance ip address for %s: %v", matches[i], err) } else { - result.Items[i].Status.HostIP = hostIP.String() + node.Status.HostIP = hostIP.String() } resources, err := instances.GetNodeResources(matches[i]) if err != nil { @@ -171,8 +292,14 @@ func (s *NodeController) cloudNodes() (*api.NodeList, error) { resources = s.staticResources } if resources != nil { - result.Items[i].Spec.Capacity = resources.Capacity + node.Spec.Capacity = resources.Capacity } + result.Items = append(result.Items, node) } return result, nil } + +// isRunningCloudProvider checks if cluster is running with cloud provider. +func (s *NodeController) isRunningCloudProvider() bool { + return s.cloud != nil && len(s.matchRE) > 0 +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/controller/nodecontroller_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/controller/nodecontroller_test.go index 5bc3b882032a..9bd47b3d8b15 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/controller/nodecontroller_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/controller/nodecontroller_test.go @@ -17,19 +17,22 @@ limitations under the License. package controller import ( + "errors" "fmt" + "net" + "reflect" + "sort" "testing" "time" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource" "github.com/GoogleCloudPlatform/kubernetes/pkg/client" fake_cloud "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/fake" + "github.com/GoogleCloudPlatform/kubernetes/pkg/probe" ) -func newNode(name string) *api.Node { - return &api.Node{ObjectMeta: api.ObjectMeta{Name: name}} -} - +// FakeNodeHandler is a fake implementation of NodesInterface and NodeInterface. type FakeNodeHandler struct { client.Fake client.FakeNodes @@ -41,6 +44,7 @@ type FakeNodeHandler struct { // Output CreatedNodes []*api.Node DeletedNodes []*api.Node + UpdatedNodes []*api.Node RequestCount int } @@ -51,7 +55,8 @@ func (c *FakeNodeHandler) Nodes() client.NodeInterface { func (m *FakeNodeHandler) Create(node *api.Node) (*api.Node, error) { defer func() { m.RequestCount++ }() if m.CreateHook == nil || m.CreateHook(m, node) { - m.CreatedNodes = append(m.CreatedNodes, node) + nodeCopy := *node + m.CreatedNodes = append(m.CreatedNodes, &nodeCopy) return node, nil } else { return nil, fmt.Errorf("Create error.") @@ -60,18 +65,27 @@ func (m *FakeNodeHandler) Create(node *api.Node) (*api.Node, error) { func (m *FakeNodeHandler) List() (*api.NodeList, error) { defer func() { m.RequestCount++ }() - nodes := []api.Node{} + var nodes []*api.Node + for i := 0; i < len(m.UpdatedNodes); i++ { + if !contains(m.UpdatedNodes[i], m.DeletedNodes) { + nodes = append(nodes, m.UpdatedNodes[i]) + } + } for i := 0; i < len(m.Existing); i++ { - if !contains(m.Existing[i], m.DeletedNodes) { - nodes = append(nodes, *m.Existing[i]) + if !contains(m.Existing[i], m.DeletedNodes) && !contains(m.Existing[i], nodes) { + nodes = append(nodes, m.Existing[i]) } } for i := 0; i < len(m.CreatedNodes); i++ { - if !contains(m.Existing[i], m.DeletedNodes) { - nodes = append(nodes, *m.CreatedNodes[i]) + if !contains(m.Existing[i], m.DeletedNodes) && !contains(m.CreatedNodes[i], nodes) { + nodes = append(nodes, m.CreatedNodes[i]) } } - return &api.NodeList{Items: nodes}, nil + nodeList := &api.NodeList{} + for _, node := range nodes { + nodeList.Items = append(nodeList.Items, *node) + } + return nodeList, nil } func (m *FakeNodeHandler) Delete(id string) error { @@ -80,142 +94,377 @@ func (m *FakeNodeHandler) Delete(id string) error { return nil } -func TestSyncStaticCreateNode(t *testing.T) { - fakeNodeHandler := &FakeNodeHandler{ - CreateHook: func(fake *FakeNodeHandler, node *api.Node) bool { - return true - }, - } - nodeController := NewNodeController(nil, ".*", []string{"node0"}, &api.NodeResources{}, fakeNodeHandler) - if err := nodeController.SyncStatic(time.Millisecond); err != nil { - t.Errorf("unexpected error: %v", err) - } +func (m *FakeNodeHandler) Update(node *api.Node) (*api.Node, error) { + nodeCopy := *node + m.UpdatedNodes = append(m.UpdatedNodes, &nodeCopy) + m.RequestCount++ + return node, nil +} - if fakeNodeHandler.RequestCount != 1 { - t.Errorf("Expected 1 call, but got %v.", fakeNodeHandler.RequestCount) - } - if len(fakeNodeHandler.CreatedNodes) != 1 { - t.Errorf("expect only 1 node created, got %v", len(fakeNodeHandler.CreatedNodes)) - } - if fakeNodeHandler.CreatedNodes[0].Name != "node0" { - t.Errorf("unexpect node %v created", fakeNodeHandler.CreatedNodes[0].Name) - } +// FakeKubeletClient is a fake implementation of KubeletClient. +type FakeKubeletClient struct { + Status probe.Status + Err error } -func TestSyncStaticCreateNodeWithHostIP(t *testing.T) { - fakeNodeHandler := &FakeNodeHandler{ - CreateHook: func(fake *FakeNodeHandler, node *api.Node) bool { - return true +func (c *FakeKubeletClient) GetPodStatus(host, podNamespace, podID string) (api.PodStatusResult, error) { + return api.PodStatusResult{}, errors.New("Not Implemented") +} + +func (c *FakeKubeletClient) HealthCheck(host string) (probe.Status, error) { + return c.Status, c.Err +} + +func TestRegisterNodes(t *testing.T) { + table := []struct { + fakeNodeHandler *FakeNodeHandler + machines []string + retryCount int + expectedRequestCount int + expectedCreateCount int + expectedFail bool + }{ + { + // Register two nodes normally. + machines: []string{"node0", "node1"}, + fakeNodeHandler: &FakeNodeHandler{ + CreateHook: func(fake *FakeNodeHandler, node *api.Node) bool { return true }, + }, + retryCount: 1, + expectedRequestCount: 2, + expectedCreateCount: 2, + expectedFail: false, + }, + { + // No machine to register. + machines: []string{}, + fakeNodeHandler: &FakeNodeHandler{ + CreateHook: func(fake *FakeNodeHandler, node *api.Node) bool { return true }, + }, + retryCount: 1, + expectedRequestCount: 0, + expectedCreateCount: 0, + expectedFail: false, + }, + { + // Fail the first two requests. + machines: []string{"node0", "node1"}, + fakeNodeHandler: &FakeNodeHandler{ + CreateHook: func(fake *FakeNodeHandler, node *api.Node) bool { + if fake.RequestCount == 0 || fake.RequestCount == 1 { + return false + } + return true + }, + }, + retryCount: 10, + expectedRequestCount: 4, + expectedCreateCount: 2, + expectedFail: false, + }, + { + // The first node always fails. + machines: []string{"node0", "node1"}, + fakeNodeHandler: &FakeNodeHandler{ + CreateHook: func(fake *FakeNodeHandler, node *api.Node) bool { + if node.Name == "node0" { + return false + } + return true + }, + }, + retryCount: 2, + expectedRequestCount: 3, // 2 for node0, 1 for node1 + expectedCreateCount: 1, + expectedFail: true, }, - } - nodeController := NewNodeController(nil, ".*", []string{"10.0.0.1"}, &api.NodeResources{}, fakeNodeHandler) - if err := nodeController.SyncStatic(time.Millisecond); err != nil { - t.Errorf("unexpected error: %v", err) } - if fakeNodeHandler.CreatedNodes[0].Name != "10.0.0.1" { - t.Errorf("unexpect node %v created", fakeNodeHandler.CreatedNodes[0].Name) - } - if fakeNodeHandler.CreatedNodes[0].Status.HostIP != "10.0.0.1" { - t.Errorf("unexpect nil node HostIP for node %v", fakeNodeHandler.CreatedNodes[0].Name) + for _, item := range table { + nodes := api.NodeList{} + for _, machine := range item.machines { + nodes.Items = append(nodes.Items, *newNode(machine)) + } + nodeController := NewNodeController(nil, "", item.machines, &api.NodeResources{}, item.fakeNodeHandler, nil) + err := nodeController.RegisterNodes(&nodes, item.retryCount, time.Millisecond) + if !item.expectedFail && err != nil { + t.Errorf("unexpected error: %v", err) + } + if item.expectedFail && err == nil { + t.Errorf("unexpected non-error") + } + if item.fakeNodeHandler.RequestCount != item.expectedRequestCount { + t.Errorf("expected %v calls, but got %v.", item.expectedRequestCount, item.fakeNodeHandler.RequestCount) + } + if len(item.fakeNodeHandler.CreatedNodes) != item.expectedCreateCount { + t.Errorf("expected %v nodes, but got %v.", item.expectedCreateCount, item.fakeNodeHandler.CreatedNodes) + } } } -func TestSyncStaticCreateNodeWithError(t *testing.T) { - fakeNodeHandler := &FakeNodeHandler{ - CreateHook: func(fake *FakeNodeHandler, node *api.Node) bool { - if fake.RequestCount == 0 { - return false - } - return true +func TestCreateStaticNodes(t *testing.T) { + table := []struct { + machines []string + expectedNodes *api.NodeList + }{ + { + machines: []string{}, + expectedNodes: &api.NodeList{}, + }, + { + machines: []string{"node0"}, + expectedNodes: &api.NodeList{ + Items: []api.Node{ + { + ObjectMeta: api.ObjectMeta{Name: "node0"}, + Spec: api.NodeSpec{}, + Status: api.NodeStatus{}, + }, + }, + }, }, - } - nodeController := NewNodeController(nil, ".*", []string{"node0"}, &api.NodeResources{}, fakeNodeHandler) - if err := nodeController.SyncStatic(time.Millisecond); err != nil { - t.Errorf("unexpected error: %v", err) } - if fakeNodeHandler.RequestCount != 2 { - t.Errorf("Expected 2 call, but got %v.", fakeNodeHandler.RequestCount) - } - if len(fakeNodeHandler.CreatedNodes) != 1 { - t.Errorf("expect only 1 node created, got %v", len(fakeNodeHandler.CreatedNodes)) - } - if fakeNodeHandler.CreatedNodes[0].Name != "node0" { - t.Errorf("unexpect node %v created", fakeNodeHandler.CreatedNodes[0].Name) + for _, item := range table { + nodeController := NewNodeController(nil, "", item.machines, &api.NodeResources{}, nil, nil) + nodes, err := nodeController.StaticNodes() + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if !reflect.DeepEqual(item.expectedNodes, nodes) { + t.Errorf("expected node list %+v, got %+v", item.expectedNodes, nodes) + } } } -func TestSyncCloudCreateNode(t *testing.T) { - fakeNodeHandler := &FakeNodeHandler{ - Existing: []*api.Node{newNode("node0")}, - } - instances := []string{"node0", "node1"} - fakeCloud := fake_cloud.FakeCloud{ - Machines: instances, - } - nodeController := NewNodeController(&fakeCloud, ".*", nil, nil, fakeNodeHandler) - if err := nodeController.SyncCloud(); err != nil { - t.Errorf("unexpected error: %v", err) +func TestCreateCloudNodes(t *testing.T) { + resourceList := api.ResourceList{ + api.ResourceCPU: *resource.NewMilliQuantity(1000, resource.DecimalSI), + api.ResourceMemory: *resource.NewQuantity(3000, resource.DecimalSI), } - if fakeNodeHandler.RequestCount != 2 { - t.Errorf("Expected 2 call, but got %v.", fakeNodeHandler.RequestCount) - } - if len(fakeNodeHandler.CreatedNodes) != 1 { - t.Errorf("expect only 1 node created, got %v", len(fakeNodeHandler.CreatedNodes)) + table := []struct { + fakeCloud *fake_cloud.FakeCloud + machines []string + expectedNodes *api.NodeList + }{ + { + fakeCloud: &fake_cloud.FakeCloud{}, + expectedNodes: &api.NodeList{}, + }, + { + fakeCloud: &fake_cloud.FakeCloud{ + Machines: []string{"node0"}, + IP: net.ParseIP("1.2.3.4"), + NodeResources: &api.NodeResources{Capacity: resourceList}, + }, + expectedNodes: &api.NodeList{ + Items: []api.Node{ + { + ObjectMeta: api.ObjectMeta{Name: "node0"}, + Spec: api.NodeSpec{Capacity: resourceList}, + Status: api.NodeStatus{HostIP: "1.2.3.4"}, + }, + }, + }, + }, } - if fakeNodeHandler.CreatedNodes[0].Name != "node1" { - t.Errorf("unexpect node %v created", fakeNodeHandler.CreatedNodes[0].Name) + + for _, item := range table { + nodeController := NewNodeController(item.fakeCloud, ".*", nil, &api.NodeResources{}, nil, nil) + nodes, err := nodeController.CloudNodes() + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if !reflect.DeepEqual(item.expectedNodes, nodes) { + t.Errorf("expected node list %+v, got %+v", item.expectedNodes, nodes) + } } } -func TestSyncCloudDeleteNode(t *testing.T) { - fakeNodeHandler := &FakeNodeHandler{ - Existing: []*api.Node{newNode("node0"), newNode("node1")}, - } - instances := []string{"node0"} - fakeCloud := fake_cloud.FakeCloud{ - Machines: instances, - } - nodeController := NewNodeController(&fakeCloud, ".*", nil, nil, fakeNodeHandler) - if err := nodeController.SyncCloud(); err != nil { - t.Errorf("unexpected error: %v", err) +func TestSyncCloud(t *testing.T) { + table := []struct { + fakeNodeHandler *FakeNodeHandler + fakeCloud *fake_cloud.FakeCloud + matchRE string + expectedRequestCount int + expectedCreated []string + expectedDeleted []string + }{ + { + fakeNodeHandler: &FakeNodeHandler{ + Existing: []*api.Node{newNode("node0")}, + }, + fakeCloud: &fake_cloud.FakeCloud{ + Machines: []string{"node0", "node1"}, + }, + matchRE: ".*", + expectedRequestCount: 2, // List + Create + expectedCreated: []string{"node1"}, + expectedDeleted: []string{}, + }, + { + fakeNodeHandler: &FakeNodeHandler{ + Existing: []*api.Node{newNode("node0"), newNode("node1")}, + }, + fakeCloud: &fake_cloud.FakeCloud{ + Machines: []string{"node0"}, + }, + matchRE: ".*", + expectedRequestCount: 2, // List + Delete + expectedCreated: []string{}, + expectedDeleted: []string{"node1"}, + }, + { + fakeNodeHandler: &FakeNodeHandler{ + Existing: []*api.Node{newNode("node0")}, + }, + fakeCloud: &fake_cloud.FakeCloud{ + Machines: []string{"node0", "node1", "fake"}, + }, + matchRE: "node[0-9]+", + expectedRequestCount: 2, // List + Create + expectedCreated: []string{"node1"}, + expectedDeleted: []string{}, + }, } - if fakeNodeHandler.RequestCount != 2 { - t.Errorf("Expected 2 call, but got %v.", fakeNodeHandler.RequestCount) - } - if len(fakeNodeHandler.DeletedNodes) != 1 { - t.Errorf("expect only 1 node deleted, got %v", len(fakeNodeHandler.DeletedNodes)) - } - if fakeNodeHandler.DeletedNodes[0].Name != "node1" { - t.Errorf("unexpect node %v created", fakeNodeHandler.DeletedNodes[0].Name) + for _, item := range table { + nodeController := NewNodeController(item.fakeCloud, item.matchRE, nil, &api.NodeResources{}, item.fakeNodeHandler, nil) + if err := nodeController.SyncCloud(); err != nil { + t.Errorf("unexpected error: %v", err) + } + if item.fakeNodeHandler.RequestCount != item.expectedRequestCount { + t.Errorf("expected %v call, but got %v.", item.expectedRequestCount, item.fakeNodeHandler.RequestCount) + } + nodes := sortedNodeNames(item.fakeNodeHandler.CreatedNodes) + if !reflect.DeepEqual(item.expectedCreated, nodes) { + t.Errorf("expected node list %+v, got %+v", item.expectedCreated, nodes) + } + nodes = sortedNodeNames(item.fakeNodeHandler.DeletedNodes) + if !reflect.DeepEqual(item.expectedDeleted, nodes) { + t.Errorf("expected node list %+v, got %+v", item.expectedDeleted, nodes) + } } } -func TestSyncCloudRegexp(t *testing.T) { - fakeNodeHandler := &FakeNodeHandler{ - Existing: []*api.Node{newNode("node0")}, - } - instances := []string{"node0", "node1", "fake"} - fakeCloud := fake_cloud.FakeCloud{ - Machines: instances, +func TestHealthCheckNode(t *testing.T) { + table := []struct { + node *api.Node + fakeKubeletClient *FakeKubeletClient + expectedConditions []api.NodeCondition + }{ + { + node: newNode("node0"), + fakeKubeletClient: &FakeKubeletClient{ + Status: probe.Success, + Err: nil, + }, + expectedConditions: []api.NodeCondition{ + { + Kind: api.NodeReady, + Status: api.ConditionFull, + }, + }, + }, + { + node: newNode("node0"), + fakeKubeletClient: &FakeKubeletClient{ + Status: probe.Failure, + Err: nil, + }, + expectedConditions: []api.NodeCondition{ + { + Kind: api.NodeReady, + Status: api.ConditionNone, + }, + }, + }, + { + node: newNode("node1"), + fakeKubeletClient: &FakeKubeletClient{ + Status: probe.Failure, + Err: errors.New("Error"), + }, + expectedConditions: []api.NodeCondition{ + { + Kind: api.NodeReady, + Status: api.ConditionUnknown, + }, + }, + }, } - nodeController := NewNodeController(&fakeCloud, "node[0-9]+", nil, nil, fakeNodeHandler) - if err := nodeController.SyncCloud(); err != nil { - t.Errorf("unexpected error: %v", err) + + for _, item := range table { + nodeController := NewNodeController(nil, "", nil, nil, nil, item.fakeKubeletClient) + conditions := nodeController.DoCheck(item.node) + if !reflect.DeepEqual(item.expectedConditions, conditions) { + t.Errorf("expected conditions %+v, got %+v", item.expectedConditions, conditions) + } } +} - if fakeNodeHandler.RequestCount != 2 { - t.Errorf("Expected 2 call, but got %v.", fakeNodeHandler.RequestCount) +func TestSyncNodeStatus(t *testing.T) { + table := []struct { + fakeNodeHandler *FakeNodeHandler + fakeKubeletClient *FakeKubeletClient + expectedNodes []*api.Node + expectedRequestCount int + }{ + { + fakeNodeHandler: &FakeNodeHandler{ + Existing: []*api.Node{newNode("node0"), newNode("node1")}, + }, + fakeKubeletClient: &FakeKubeletClient{ + Status: probe.Success, + Err: nil, + }, + expectedNodes: []*api.Node{ + { + ObjectMeta: api.ObjectMeta{Name: "node0"}, + Status: api.NodeStatus{Conditions: []api.NodeCondition{{Kind: api.NodeReady, Status: api.ConditionFull}}}, + }, + { + ObjectMeta: api.ObjectMeta{Name: "node1"}, + Status: api.NodeStatus{Conditions: []api.NodeCondition{{Kind: api.NodeReady, Status: api.ConditionFull}}}, + }, + }, + expectedRequestCount: 3, // List + 2xUpdate + }, } - if len(fakeNodeHandler.CreatedNodes) != 1 { - t.Errorf("expect only 1 node created, got %v", len(fakeNodeHandler.CreatedNodes)) + + for _, item := range table { + nodeController := NewNodeController(nil, "", nil, nil, item.fakeNodeHandler, item.fakeKubeletClient) + if err := nodeController.SyncNodeStatus(); err != nil { + t.Errorf("unexpected error: %v", err) + } + if item.fakeNodeHandler.RequestCount != item.expectedRequestCount { + t.Errorf("expected %v call, but got %v.", item.expectedRequestCount, item.fakeNodeHandler.RequestCount) + } + if !reflect.DeepEqual(item.expectedNodes, item.fakeNodeHandler.UpdatedNodes) { + t.Errorf("expected nodes %+v, got %+v", item.expectedNodes, item.fakeNodeHandler.UpdatedNodes) + } + item.fakeNodeHandler.RequestCount = 0 + if err := nodeController.SyncNodeStatus(); err != nil { + t.Errorf("unexpected error: %v", err) + } + if item.fakeNodeHandler.RequestCount != 1 { + t.Errorf("expected one list for updating same status, but got %v.", item.fakeNodeHandler.RequestCount) + } } - if fakeNodeHandler.CreatedNodes[0].Name != "node1" { - t.Errorf("unexpect node %v created", fakeNodeHandler.CreatedNodes[0].Name) +} + +func newNode(name string) *api.Node { + return &api.Node{ObjectMeta: api.ObjectMeta{Name: name}} +} + +func sortedNodeNames(nodes []*api.Node) []string { + nodeNames := []string{} + for _, node := range nodes { + nodeNames = append(nodeNames, node.Name) } + sort.Strings(nodeNames) + return nodeNames } func contains(node *api.Node, nodes []*api.Node) bool { diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/gce/gce.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/gce/gce.go index 65e62f6d915d..529c810643e5 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/gce/gce.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/gce/gce.go @@ -37,6 +37,7 @@ import ( "github.com/golang/glog" "golang.org/x/oauth2" "golang.org/x/oauth2/google" + "google.golang.org/cloud/compute/metadata" ) // GCECloud is an implementation of Interface, TCPLoadBalancer and Instances for Google Compute Engine. @@ -72,8 +73,7 @@ func getMetadata(url string) (string, error) { } func getProjectAndZone() (string, string, error) { - url := "http://metadata/computeMetadata/v1/instance/zone" - result, err := getMetadata(url) + result, err := metadata.Get("instance/zone") if err != nil { return "", "", err } @@ -85,8 +85,7 @@ func getProjectAndZone() (string, string, error) { } func getInstanceID() (string, error) { - url := "http://metadata/computeMetadata/v1/instance/hostname" - result, err := getMetadata(url) + result, err := metadata.Get("instance/hostname") if err != nil { return "", err } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/controller/replication_controller.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/controller/replication_controller.go index b347d94c72c8..704384edd1b6 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/controller/replication_controller.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/controller/replication_controller.go @@ -17,6 +17,7 @@ limitations under the License. package controller import ( + "fmt" "sync" "time" @@ -65,15 +66,15 @@ func (r RealPodControl) createReplica(namespace string, controller api.Replicati }, } if err := api.Scheme.Convert(&controller.Spec.Template.Spec, &pod.Spec); err != nil { - glog.Errorf("Unable to convert pod template: %v", err) + util.HandleError(fmt.Errorf("unable to convert pod template: %v", err)) return } if labels.Set(pod.Labels).AsSelector().Empty() { - glog.Errorf("Unable to create pod replica, no labels") + util.HandleError(fmt.Errorf("unable to create pod replica, no labels")) return } if _, err := r.kubeClient.Pods(namespace).Create(pod); err != nil { - glog.Errorf("Unable to create pod replica: %v", err) + util.HandleError(fmt.Errorf("unable to create pod replica: %v", err)) } } @@ -108,7 +109,7 @@ func (rm *ReplicationManager) watchControllers(resourceVersion *string) { *resourceVersion, ) if err != nil { - glog.Errorf("Unexpected failure to watch: %v", err) + util.HandleError(fmt.Errorf("unable to watch: %v", err)) time.Sleep(5 * time.Second) return } @@ -125,13 +126,13 @@ func (rm *ReplicationManager) watchControllers(resourceVersion *string) { return } if event.Type == watch.Error { - glog.Errorf("error from watch during sync: %v", errors.FromObject(event.Object)) + util.HandleError(fmt.Errorf("error from watch during sync: %v", errors.FromObject(event.Object))) continue } glog.V(4).Infof("Got watch: %#v", event) rc, ok := event.Object.(*api.ReplicationController) if !ok { - glog.Errorf("unexpected object: %#v", event.Object) + util.HandleError(fmt.Errorf("unexpected object: %#v", event.Object)) continue } // If we get disconnected, start where we left off. @@ -140,7 +141,7 @@ func (rm *ReplicationManager) watchControllers(resourceVersion *string) { // it in the desired state. glog.V(4).Infof("About to sync from watch: %v", rc.Name) if err := rm.syncHandler(*rc); err != nil { - glog.Errorf("unexpected sync. error: %v", err) + util.HandleError(fmt.Errorf("unexpected sync error: %v", err)) } } } @@ -199,7 +200,7 @@ func (rm *ReplicationManager) synchronize() { var controllers []api.ReplicationController list, err := rm.kubeClient.ReplicationControllers(api.NamespaceAll).List(labels.Everything()) if err != nil { - glog.Errorf("Synchronization error: %v (%#v)", err, err) + util.HandleError(fmt.Errorf("synchronization error: %v", err)) return } controllers = list.Items @@ -211,7 +212,7 @@ func (rm *ReplicationManager) synchronize() { glog.V(4).Infof("periodic sync of %v", controllers[ix].Name) err := rm.syncHandler(controllers[ix]) if err != nil { - glog.Errorf("Error synchronizing: %v", err) + util.HandleError(fmt.Errorf("error synchronizing: %v", err)) } }(ix) } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/controller/replication_controller_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/controller/replication_controller_test.go index 5673a1653c94..a2df341b8f89 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/controller/replication_controller_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/controller/replication_controller_test.go @@ -83,6 +83,9 @@ func newReplicationController(replicas int) api.ReplicationController { Image: "foo/bar", }, }, + NodeSelector: map[string]string{ + "baz": "blah", + }, }, }, }, @@ -209,6 +212,9 @@ func TestCreateReplica(t *testing.T) { Image: "foo/bar", }, }, + NodeSelector: map[string]string{ + "foo": "bar", + }, }, }, }, diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider/config.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider/config.go index b44750409d39..7e4c2298fcb2 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider/config.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider/config.go @@ -25,6 +25,7 @@ import ( "os" "path/filepath" "strings" + "sync" "github.com/golang/glog" ) @@ -40,28 +41,52 @@ type DockerConfigEntry struct { Email string } -const ( - dockerConfigFileLocation = ".dockercfg" +var ( + preferredPathLock sync.Mutex + preferredPath = "" + workingDirPath = "" + homeDirPath = os.Getenv("HOME") + rootDirPath = "/" + + configFileName = ".dockercfg" ) +func SetPreferredDockercfgPath(path string) { + preferredPathLock.Lock() + defer preferredPathLock.Unlock() + preferredPath = path +} + +func GetPreferredDockercfgPath() string { + preferredPathLock.Lock() + defer preferredPathLock.Unlock() + return preferredPath +} + func ReadDockerConfigFile() (cfg DockerConfig, err error) { - // TODO(mattmoor): This causes the Kubelet to read /.dockercfg, - // which is incorrect. It should come from $HOME/.dockercfg. - absDockerConfigFileLocation, err := filepath.Abs(dockerConfigFileLocation) - if err != nil { - glog.Errorf("while trying to canonicalize %s: %v", dockerConfigFileLocation, err) - } - glog.V(2).Infof("looking for .dockercfg at %s", absDockerConfigFileLocation) - contents, err := ioutil.ReadFile(absDockerConfigFileLocation) - if os.IsNotExist(err) { - return make(DockerConfig), nil - } - if err != nil { - glog.Errorf("while trying to read %s: %v", absDockerConfigFileLocation, err) - return nil, err + dockerConfigFileLocations := []string{GetPreferredDockercfgPath(), workingDirPath, homeDirPath, rootDirPath} + for _, configPath := range dockerConfigFileLocations { + absDockerConfigFileLocation, err := filepath.Abs(filepath.Join(configPath, configFileName)) + if err != nil { + glog.Errorf("while trying to canonicalize %s: %v", configPath, err) + continue + } + glog.V(4).Infof("looking for .dockercfg at %s", absDockerConfigFileLocation) + contents, err := ioutil.ReadFile(absDockerConfigFileLocation) + if os.IsNotExist(err) { + continue + } + if err != nil { + glog.V(4).Infof("while trying to read %s: %v", absDockerConfigFileLocation, err) + continue + } + cfg, err := readDockerConfigFileFromBytes(contents) + if err == nil { + glog.V(4).Infof("found .dockercfg at %s", absDockerConfigFileLocation) + return cfg, nil + } } - - return readDockerConfigFileFromBytes(contents) + return nil, fmt.Errorf("couldn't find valid .dockercfg after checking in %v", dockerConfigFileLocations) } // HttpError wraps a non-StatusOK error code as an error. diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider/keyring.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider/keyring.go index 518cacb4aeff..6132c04bfa05 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider/keyring.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider/keyring.go @@ -66,9 +66,20 @@ func (dk *BasicDockerKeyring) Add(cfg DockerConfig) { continue } - registry := parsed.Host + parsed.Path - dk.creds[registry] = creds - dk.index = append(dk.index, registry) + // The docker client allows exact matches: + // foo.bar.com/namespace + // Or hostname matches: + // foo.bar.com + // See ResolveAuthConfig in docker/registry/auth.go. + if parsed.Host != "" { + // NOTE: foo.bar.com comes through as Path. + dk.creds[parsed.Host] = creds + dk.index = append(dk.index, parsed.Host) + } + if parsed.Path != "/" { + dk.creds[parsed.Host+parsed.Path] = creds + dk.index = append(dk.index, parsed.Host+parsed.Path) + } } // Update the index used to identify which credentials to use for a given diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider/provider.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider/provider.go index 9ce5e93a5531..14d1512ab7ee 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider/provider.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider/provider.go @@ -68,7 +68,7 @@ func (d *defaultDockerConfigProvider) Provide() DockerConfig { if cfg, err := ReadDockerConfigFile(); err == nil { return cfg } else if !os.IsNotExist(err) { - glog.V(1).Infof("Unable to parse Docker config file: %v", err) + glog.V(4).Infof("Unable to parse Docker config file: %v", err) } return DockerConfig{} } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/exec.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/exec.go deleted file mode 100644 index 9f0ad4434c12..000000000000 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/exec.go +++ /dev/null @@ -1,59 +0,0 @@ -/* -Copyright 2014 Google Inc. All rights reserved. - -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 health - -import ( - "fmt" - "strings" - - "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - "github.com/GoogleCloudPlatform/kubernetes/pkg/types" - "github.com/golang/glog" -) - -const defaultHealthyOutput = "ok" - -type CommandRunner interface { - RunInContainer(podFullName string, uid types.UID, containerName string, cmd []string) ([]byte, error) -} - -type ExecHealthChecker struct { - runner CommandRunner -} - -func NewExecHealthChecker(runner CommandRunner) HealthChecker { - return &ExecHealthChecker{runner} -} - -func (e *ExecHealthChecker) HealthCheck(podFullName string, podUID types.UID, status api.PodStatus, container api.Container) (Status, error) { - if container.LivenessProbe.Exec == nil { - return Unknown, fmt.Errorf("missing exec parameters") - } - data, err := e.runner.RunInContainer(podFullName, podUID, container.Name, container.LivenessProbe.Exec.Command) - glog.V(1).Infof("container %s health check response: %s", podFullName, string(data)) - if err != nil { - return Unknown, err - } - if strings.ToLower(string(data)) != defaultHealthyOutput { - return Unhealthy, nil - } - return Healthy, nil -} - -func (e *ExecHealthChecker) CanCheck(probe *api.LivenessProbe) bool { - return probe.Exec != nil -} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/exec_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/exec_test.go deleted file mode 100644 index a9aa2199c894..000000000000 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/exec_test.go +++ /dev/null @@ -1,85 +0,0 @@ -/* -Copyright 2014 Google Inc. All rights reserved. - -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 health - -import ( - "fmt" - "reflect" - "testing" - - "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - "github.com/GoogleCloudPlatform/kubernetes/pkg/types" -) - -type FakeExec struct { - cmd []string - out []byte - err error -} - -func (f *FakeExec) RunInContainer(podFullName string, uid types.UID, container string, cmd []string) ([]byte, error) { - f.cmd = cmd - return f.out, f.err -} - -type healthCheckTest struct { - expectedStatus Status - probe *api.LivenessProbe - expectError bool - output []byte - err error -} - -func TestExec(t *testing.T) { - fake := FakeExec{} - checker := ExecHealthChecker{&fake} - tests := []healthCheckTest{ - // Missing parameters - {Unknown, &api.LivenessProbe{}, true, nil, nil}, - // Ok - {Healthy, &api.LivenessProbe{ - Exec: &api.ExecAction{Command: []string{"ls", "-l"}}, - }, false, []byte("OK"), nil}, - // Run returns error - {Unknown, &api.LivenessProbe{ - Exec: &api.ExecAction{ - Command: []string{"ls", "-l"}, - }, - }, true, []byte("OK, NOT"), fmt.Errorf("test error")}, - // Unhealthy - {Unhealthy, &api.LivenessProbe{ - Exec: &api.ExecAction{Command: []string{"ls", "-l"}}, - }, false, []byte("Fail"), nil}, - } - for _, test := range tests { - fake.out = test.output - fake.err = test.err - status, err := checker.HealthCheck("test", "", api.PodStatus{}, api.Container{LivenessProbe: test.probe}) - if status != test.expectedStatus { - t.Errorf("expected %v, got %v", test.expectedStatus, status) - } - if err != nil && test.expectError == false { - t.Errorf("unexpected error: %v", err) - } - if err == nil && test.expectError == true { - t.Errorf("unexpected non-error") - } - if test.probe.Exec != nil && !reflect.DeepEqual(fake.cmd, test.probe.Exec.Command) { - t.Errorf("expected: %v, got %v", test.probe.Exec.Command, fake.cmd) - } - } -} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/health.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/health.go deleted file mode 100644 index 64233e166ee8..000000000000 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/health.go +++ /dev/null @@ -1,115 +0,0 @@ -/* -Copyright 2014 Google Inc. All rights reserved. - -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 health - -import ( - "sync" - - "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - "github.com/GoogleCloudPlatform/kubernetes/pkg/types" - "github.com/golang/glog" -) - -// Status represents the result of a single health-check operation. -type Status int - -// Status values must be one of these constants. -const ( - Healthy Status = iota - Unhealthy - Unknown -) - -// HealthChecker defines an abstract interface for checking container health. -type HealthChecker interface { - HealthCheck(podFullName string, podUID types.UID, status api.PodStatus, container api.Container) (Status, error) - CanCheck(probe *api.LivenessProbe) bool -} - -// protects allCheckers -var checkerLock = sync.Mutex{} -var allCheckers = []HealthChecker{} - -// AddHealthChecker adds a health checker to the list of known HealthChecker objects. -// Any subsequent call to NewHealthChecker will know about this HealthChecker. -func AddHealthChecker(checker HealthChecker) { - checkerLock.Lock() - defer checkerLock.Unlock() - allCheckers = append(allCheckers, checker) -} - -// NewHealthChecker creates a new HealthChecker which supports multiple types of liveness probes. -func NewHealthChecker() HealthChecker { - checkerLock.Lock() - defer checkerLock.Unlock() - return &muxHealthChecker{ - checkers: append([]HealthChecker{}, allCheckers...), - } -} - -// muxHealthChecker bundles multiple implementations of HealthChecker of different types. -type muxHealthChecker struct { - // Given a LivenessProbe, cycle through each known checker and see if it supports - // the specific kind of probe (by returning non-nil). - checkers []HealthChecker -} - -func (m *muxHealthChecker) findCheckerFor(probe *api.LivenessProbe) HealthChecker { - for i := range m.checkers { - if m.checkers[i].CanCheck(probe) { - return m.checkers[i] - } - } - return nil -} - -// HealthCheck delegates the health-checking of the container to one of the bundled implementations. -// If there is no health checker that can check container it returns Unknown, nil. -func (m *muxHealthChecker) HealthCheck(podFullName string, podUID types.UID, status api.PodStatus, container api.Container) (Status, error) { - checker := m.findCheckerFor(container.LivenessProbe) - if checker == nil { - glog.Warningf("Failed to find health checker for %s %+v", container.Name, container.LivenessProbe) - return Unknown, nil - } - return checker.HealthCheck(podFullName, podUID, status, container) -} - -func (m *muxHealthChecker) CanCheck(probe *api.LivenessProbe) bool { - return m.findCheckerFor(probe) != nil -} - -// findPortByName is a helper function to look up a port in a container by name. -// Returns the HostPort if found, -1 if not found. -func findPortByName(container api.Container, portName string) int { - for _, port := range container.Ports { - if port.Name == portName { - return port.HostPort - } - } - return -1 -} - -func (s Status) String() string { - switch s { - case Healthy: - return "healthy" - case Unhealthy: - return "unhealthy" - default: - return "unknown" - } -} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/health_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/health_test.go deleted file mode 100644 index c3b29aad4824..000000000000 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/health_test.go +++ /dev/null @@ -1,142 +0,0 @@ -/* -Copyright 2014 Google Inc. All rights reserved. - -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 health - -import ( - "net" - "net/http" - "net/http/httptest" - "net/url" - "testing" - - "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - "github.com/GoogleCloudPlatform/kubernetes/pkg/util" -) - -const statusServerEarlyShutdown = -1 - -func TestHealthChecker(t *testing.T) { - AddHealthChecker(&HTTPHealthChecker{client: &http.Client{}}) - var healthCheckerTests = []struct { - status int - health Status - }{ - {http.StatusOK, Healthy}, - {statusServerEarlyShutdown, Unhealthy}, - {http.StatusBadRequest, Unhealthy}, - {http.StatusBadGateway, Unhealthy}, - {http.StatusInternalServerError, Unhealthy}, - } - for _, healthCheckerTest := range healthCheckerTests { - tt := healthCheckerTest - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(tt.status) - })) - defer ts.Close() - u, err := url.Parse(ts.URL) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - host, port, err := net.SplitHostPort(u.Host) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - if tt.status == statusServerEarlyShutdown { - ts.Close() - } - container := api.Container{ - LivenessProbe: &api.LivenessProbe{ - HTTPGet: &api.HTTPGetAction{ - Port: util.NewIntOrStringFromString(port), - Path: "/foo/bar", - Host: host, - }, - }, - } - hc := NewHealthChecker() - health, err := hc.HealthCheck("test", "", api.PodStatus{}, container) - if err != nil && tt.health != Unhealthy { - t.Errorf("Unexpected error: %v", err) - } - if health != tt.health { - t.Errorf("Expected %v, got %v", tt.health, health) - } - } -} - -func TestFindPortByName(t *testing.T) { - container := api.Container{ - Ports: []api.Port{ - { - Name: "foo", - HostPort: 8080, - }, - { - Name: "bar", - HostPort: 9000, - }, - }, - } - want := 8080 - got := findPortByName(container, "foo") - if got != want { - t.Errorf("Expected %v, got %v", want, got) - } -} - -func TestMuxHealthChecker(t *testing.T) { - muxHealthCheckerTests := []struct { - health Status - }{ - // TODO: This test should run through a few different checker types. - {Healthy}, - } - mc := &muxHealthChecker{ - checkers: []HealthChecker{ - &HTTPHealthChecker{client: &http.Client{}}, - }, - } - for _, muxHealthCheckerTest := range muxHealthCheckerTests { - tt := muxHealthCheckerTest - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusOK) - })) - defer ts.Close() - u, err := url.Parse(ts.URL) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - host, port, err := net.SplitHostPort(u.Host) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - container := api.Container{ - LivenessProbe: &api.LivenessProbe{ - HTTPGet: &api.HTTPGetAction{}, - }, - } - container.LivenessProbe.HTTPGet.Port = util.NewIntOrStringFromString(port) - container.LivenessProbe.HTTPGet.Host = host - health, err := mc.HealthCheck("test", "", api.PodStatus{}, container) - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - if health != tt.health { - t.Errorf("Expected %v, got %v", tt.health, health) - } - } -} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/http.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/http.go deleted file mode 100644 index f5b447938871..000000000000 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/http.go +++ /dev/null @@ -1,119 +0,0 @@ -/* -Copyright 2014 Google Inc. All rights reserved. - -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 health - -import ( - "fmt" - "net" - "net/http" - "net/url" - "strconv" - - "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - "github.com/GoogleCloudPlatform/kubernetes/pkg/types" - "github.com/GoogleCloudPlatform/kubernetes/pkg/util" - "github.com/golang/glog" -) - -// HTTPGetInterface is an abstract interface for testability. It abstracts the interface of http.Client.Get. -// This is exported because some other packages may want to do direct HTTP checks. -type HTTPGetInterface interface { - Get(url string) (*http.Response, error) -} - -// HTTPHealthChecker is an implementation of HealthChecker which checks container health by sending HTTP Get requests. -type HTTPHealthChecker struct { - client HTTPGetInterface -} - -func NewHTTPHealthChecker(client *http.Client) HealthChecker { - return &HTTPHealthChecker{client: &http.Client{}} -} - -// getURLParts parses the components of the target URL. For testability. -func getURLParts(status api.PodStatus, container api.Container) (string, int, string, error) { - params := container.LivenessProbe.HTTPGet - if params == nil { - return "", -1, "", fmt.Errorf("no HTTP parameters specified: %v", container) - } - port := -1 - switch params.Port.Kind { - case util.IntstrInt: - port = params.Port.IntVal - case util.IntstrString: - port = findPortByName(container, params.Port.StrVal) - if port == -1 { - // Last ditch effort - maybe it was an int stored as string? - var err error - if port, err = strconv.Atoi(params.Port.StrVal); err != nil { - return "", -1, "", err - } - } - } - if port == -1 { - return "", -1, "", fmt.Errorf("unknown port: %v", params.Port) - } - var host string - if len(params.Host) > 0 { - host = params.Host - } else { - host = status.PodIP - } - - return host, port, params.Path, nil -} - -// formatURL formats a URL from args. For testability. -func formatURL(host string, port int, path string) string { - u := url.URL{ - Scheme: "http", - Host: net.JoinHostPort(host, strconv.Itoa(port)), - Path: path, - } - return u.String() -} - -// DoHTTPCheck checks if a GET request to the url succeeds. -// If the HTTP response code is successful (i.e. 400 > code >= 200), it returns Healthy. -// If the HTTP response code is unsuccessful or HTTP communication fails, it returns Unhealthy. -// This is exported because some other packages may want to do direct HTTP checks. -func DoHTTPCheck(url string, client HTTPGetInterface) (Status, error) { - res, err := client.Get(url) - if err != nil { - glog.V(1).Infof("HTTP probe error: %v", err) - return Unhealthy, nil - } - defer res.Body.Close() - if res.StatusCode >= http.StatusOK && res.StatusCode < http.StatusBadRequest { - return Healthy, nil - } - glog.V(1).Infof("Health check failed for %s, Response: %v", url, *res) - return Unhealthy, nil -} - -// HealthCheck checks if the container is healthy by trying sending HTTP Get requests to the container. -func (h *HTTPHealthChecker) HealthCheck(podFullName string, podUID types.UID, status api.PodStatus, container api.Container) (Status, error) { - host, port, path, err := getURLParts(status, container) - if err != nil { - return Unknown, err - } - return DoHTTPCheck(formatURL(host, port, path), h.client) -} - -func (h *HTTPHealthChecker) CanCheck(probe *api.LivenessProbe) bool { - return probe.HTTPGet != nil -} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/tcp.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/tcp.go deleted file mode 100644 index 039e82d140cd..000000000000 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/tcp.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 2014 Google Inc. All rights reserved. - -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 health - -import ( - "fmt" - "net" - "strconv" - - "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - "github.com/GoogleCloudPlatform/kubernetes/pkg/types" - "github.com/GoogleCloudPlatform/kubernetes/pkg/util" - "github.com/golang/glog" -) - -type TCPHealthChecker struct{} - -// getTCPAddrParts parses the components of a TCP connection address. For testability. -func getTCPAddrParts(status api.PodStatus, container api.Container) (string, int, error) { - params := container.LivenessProbe.TCPSocket - if params == nil { - return "", -1, fmt.Errorf("error, no TCP parameters specified: %v", container) - } - port := -1 - switch params.Port.Kind { - case util.IntstrInt: - port = params.Port.IntVal - case util.IntstrString: - port = findPortByName(container, params.Port.StrVal) - if port == -1 { - // Last ditch effort - maybe it was an int stored as string? - var err error - if port, err = strconv.Atoi(params.Port.StrVal); err != nil { - return "", -1, err - } - } - } - if port == -1 { - return "", -1, fmt.Errorf("unknown port: %v", params.Port) - } - if len(status.PodIP) == 0 { - return "", -1, fmt.Errorf("no host specified.") - } - - return status.PodIP, port, nil -} - -// DoTCPCheck checks that a TCP socket to the address can be opened. -// If the socket can be opened, it returns Healthy. -// If the socket fails to open, it returns Unhealthy. -// This is exported because some other packages may want to do direct TCP checks. -func DoTCPCheck(addr string) (Status, error) { - conn, err := net.Dial("tcp", addr) - if err != nil { - return Unhealthy, nil - } - err = conn.Close() - if err != nil { - glog.Errorf("unexpected error closing health check socket: %v (%#v)", err, err) - } - return Healthy, nil -} - -func (t *TCPHealthChecker) HealthCheck(podFullName string, podUID types.UID, status api.PodStatus, container api.Container) (Status, error) { - host, port, err := getTCPAddrParts(status, container) - if err != nil { - return Unknown, err - } - return DoTCPCheck(net.JoinHostPort(host, strconv.Itoa(port))) -} - -func (t *TCPHealthChecker) CanCheck(probe *api.LivenessProbe) bool { - return probe.TCPSocket != nil -} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/tcp_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/tcp_test.go deleted file mode 100644 index b693a9731f6b..000000000000 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/tcp_test.go +++ /dev/null @@ -1,115 +0,0 @@ -/* -Copyright 2014 Google Inc. All rights reserved. - -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 health - -import ( - "net" - "net/http" - "net/http/httptest" - "net/url" - "testing" - - "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - "github.com/GoogleCloudPlatform/kubernetes/pkg/util" -) - -func TestGetTCPAddrParts(t *testing.T) { - testCases := []struct { - probe *api.TCPSocketAction - ok bool - host string - port int - }{ - {&api.TCPSocketAction{Port: util.NewIntOrStringFromInt(-1)}, false, "", -1}, - {&api.TCPSocketAction{Port: util.NewIntOrStringFromString("")}, false, "", -1}, - {&api.TCPSocketAction{Port: util.NewIntOrStringFromString("-1")}, false, "", -1}, - {&api.TCPSocketAction{Port: util.NewIntOrStringFromString("not-found")}, false, "", -1}, - {&api.TCPSocketAction{Port: util.NewIntOrStringFromString("found")}, true, "1.2.3.4", 93}, - {&api.TCPSocketAction{Port: util.NewIntOrStringFromInt(76)}, true, "1.2.3.4", 76}, - {&api.TCPSocketAction{Port: util.NewIntOrStringFromString("118")}, true, "1.2.3.4", 118}, - } - - for _, test := range testCases { - state := api.PodStatus{PodIP: "1.2.3.4"} - container := api.Container{ - Ports: []api.Port{{Name: "found", HostPort: 93}}, - LivenessProbe: &api.LivenessProbe{ - TCPSocket: test.probe, - }, - } - host, port, err := getTCPAddrParts(state, container) - if !test.ok && err == nil { - t.Errorf("Expected error for %+v, got %s:%d", test, host, port) - } - if test.ok && err != nil { - t.Errorf("Unexpected error: %v", err) - } - if test.ok { - if host != test.host || port != test.port { - t.Errorf("Expected %s:%d, got %s:%d", test.host, test.port, host, port) - } - } - } -} - -func TestTcpHealthChecker(t *testing.T) { - tests := []struct { - probe *api.TCPSocketAction - expectedStatus Status - expectError bool - }{ - // The probe will be filled in below. This is primarily testing that a connection is made. - {&api.TCPSocketAction{}, Healthy, false}, - {&api.TCPSocketAction{}, Unhealthy, false}, - {nil, Unknown, true}, - } - - checker := &TCPHealthChecker{} - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusOK) - })) - defer server.Close() - u, err := url.Parse(server.URL) - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - host, port, err := net.SplitHostPort(u.Host) - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - for _, test := range tests { - container := api.Container{ - LivenessProbe: &api.LivenessProbe{ - TCPSocket: test.probe, - }, - } - params := container.LivenessProbe.TCPSocket - if params != nil && test.expectedStatus == Healthy { - params.Port = util.NewIntOrStringFromString(port) - } - status, err := checker.HealthCheck("test", "", api.PodStatus{PodIP: host}, container) - if status != test.expectedStatus { - t.Errorf("expected: %v, got: %v", test.expectedStatus, status) - } - if err != nil && !test.expectError { - t.Errorf("unexpected error: %#v", err) - } - if err == nil && test.expectError { - t.Errorf("unexpected non-error.") - } - } -} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubecfg/resource_printer_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubecfg/resource_printer_test.go index 19db87de636f..f8253b435432 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubecfg/resource_printer_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubecfg/resource_printer_test.go @@ -181,7 +181,7 @@ func TestTemplateEmitsVersionedObjects(t *testing.T) { } func TestTemplatePanic(t *testing.T) { - tmpl := `{{and ((index .currentState.info "update-demo").state.running.startedAt) .currentState.info.net.state.running.startedAt}}` + tmpl := `{{and ((index .currentState.info "foo").state.running.startedAt) .currentState.info.net.state.running.startedAt}}` printer, err := NewTemplatePrinter([]byte(tmpl)) if err != nil { t.Fatalf("tmpl fail: %v", err) @@ -204,18 +204,18 @@ func TestTemplateStrings(t *testing.T) { }{ "nilInfo": {api.Pod{}, "false"}, "emptyInfo": {api.Pod{Status: api.PodStatus{Info: api.PodInfo{}}}, "false"}, - "containerExists": { + "fooExists": { api.Pod{ Status: api.PodStatus{ - Info: api.PodInfo{"update-demo": api.ContainerStatus{}}, + Info: api.PodInfo{"foo": api.ContainerStatus{}}, }, }, "false", }, - "netExists": { + "barExists": { api.Pod{ Status: api.PodStatus{ - Info: api.PodInfo{"net": api.ContainerStatus{}}, + Info: api.PodInfo{"bar": api.ContainerStatus{}}, }, }, "false", @@ -224,8 +224,8 @@ func TestTemplateStrings(t *testing.T) { api.Pod{ Status: api.PodStatus{ Info: api.PodInfo{ - "update-demo": api.ContainerStatus{}, - "net": api.ContainerStatus{}, + "foo": api.ContainerStatus{}, + "bar": api.ContainerStatus{}, }, }, }, @@ -235,8 +235,8 @@ func TestTemplateStrings(t *testing.T) { api.Pod{ Status: api.PodStatus{ Info: api.PodInfo{ - "update-demo": api.ContainerStatus{}, - "net": api.ContainerStatus{ + "foo": api.ContainerStatus{}, + "bar": api.ContainerStatus{ State: api.ContainerState{ Running: &api.ContainerStateRunning{ StartedAt: util.Time{}, @@ -252,14 +252,14 @@ func TestTemplateStrings(t *testing.T) { api.Pod{ Status: api.PodStatus{ Info: api.PodInfo{ - "update-demo": api.ContainerStatus{ + "foo": api.ContainerStatus{ State: api.ContainerState{ Running: &api.ContainerStateRunning{ StartedAt: util.Time{}, }, }, }, - "net": api.ContainerStatus{ + "bar": api.ContainerStatus{ State: api.ContainerState{ Running: &api.ContainerStateRunning{ StartedAt: util.Time{}, @@ -276,14 +276,14 @@ func TestTemplateStrings(t *testing.T) { // The point of this test is to verify that the below template works. If you change this // template, you need to update hack/e2e-suite/update.sh. tmpl := - `{{and (exists . "currentState" "info" "update-demo" "state" "running") (exists . "currentState" "info" "net" "state" "running")}}` + `{{and (exists . "currentState" "info" "foo" "state" "running") (exists . "currentState" "info" "bar" "state" "running")}}` useThisToDebug := ` a: {{exists . "currentState"}} b: {{exists . "currentState" "info"}} -c: {{exists . "currentState" "info" "update-demo"}} -d: {{exists . "currentState" "info" "update-demo" "state"}} -e: {{exists . "currentState" "info" "update-demo" "state" "running"}} -f: {{exists . "currentState" "info" "update-demo" "state" "running" "startedAt"}}` +c: {{exists . "currentState" "info" "foo"}} +d: {{exists . "currentState" "info" "foo" "state"}} +e: {{exists . "currentState" "info" "foo" "state" "running"}} +f: {{exists . "currentState" "info" "foo" "state" "running" "startedAt"}}` _ = useThisToDebug // don't complain about unused var printer, err := NewTemplatePrinter([]byte(tmpl)) diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/cmd.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/cmd.go index 2a94c6efc35a..a3eeb2f6f146 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/cmd.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/cmd.go @@ -329,17 +329,19 @@ func (c *clientCache) ClientConfigForVersion(version string) (*client.Config, er return nil, err } c.defaultConfig = config - if c.matchVersion { if err := client.MatchesServerVersion(config); err != nil { return nil, err } } } - // TODO: have a better config copy method config := *c.defaultConfig + if len(version) != 0 { + config.Version = version + } client.SetKubernetesDefaults(&config) + return &config, nil } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/cmd_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/cmd_test.go index 50dc9315a376..b007a3a30e86 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/cmd_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/cmd_test.go @@ -21,6 +21,7 @@ import ( "fmt" "io" "io/ioutil" + "testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" @@ -172,3 +173,27 @@ func objBody(codec runtime.Codec, obj runtime.Object) io.ReadCloser { func stringBody(body string) io.ReadCloser { return ioutil.NopCloser(bytes.NewReader([]byte(body))) } + +// Verify that resource.RESTClients constructed from a factory respect mapping.APIVersion +func TestClientVersions(t *testing.T) { + f := NewFactory(nil) + + versions := []string{ + "v1beta1", + "v1beta2", + "v1beta3", + } + for _, version := range versions { + mapping := &meta.RESTMapping{ + APIVersion: version, + } + c, err := f.RESTClient(nil, mapping) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + client := c.(*client.RESTClient) + if client.APIVersion() != version { + t.Errorf("unexpected Client APIVersion: %s %v", client.APIVersion, client) + } + } +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/config/config_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/config/config_test.go index 069760872cb2..60949928e5a5 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/config/config_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/config/config_test.go @@ -35,7 +35,7 @@ func newRedFederalCowHammerConfig() clientcmdapi.Config { Clusters: map[string]clientcmdapi.Cluster{ "cow-cluster": {Server: "http://cow.org:8080"}}, Contexts: map[string]clientcmdapi.Context{ - "federal-context": {AuthInfo: "red-user", Cluster: "cow-cluster", Namespace: "hammer-ns"}}, + "federal-context": {AuthInfo: "red-user", Cluster: "cow-cluster"}}, } } @@ -166,11 +166,11 @@ func TestAdditionalAuth(t *testing.T) { test.run(t) } -func TestOverwriteExistingAuth(t *testing.T) { +func TestMergeExistingAuth(t *testing.T) { expectedConfig := newRedFederalCowHammerConfig() - authInfo := clientcmdapi.NewAuthInfo() + authInfo := expectedConfig.AuthInfos["red-user"] authInfo.AuthPath = "auth-path" - expectedConfig.AuthInfos["red-user"] = *authInfo + expectedConfig.AuthInfos["red-user"] = authInfo test := configCommandTest{ args: []string{"set-credentials", "red-user", "--" + clientcmd.FlagAuthPath + "=auth-path"}, startingConfig: newRedFederalCowHammerConfig(), @@ -252,14 +252,14 @@ func TestAdditionalContext(t *testing.T) { test.run(t) } -func TestOverwriteExistingContext(t *testing.T) { +func TestMergeExistingContext(t *testing.T) { expectedConfig := newRedFederalCowHammerConfig() - context := *clientcmdapi.NewContext() - context.Cluster = "clustername" + context := expectedConfig.Contexts["federal-context"] + context.Namespace = "hammer" expectedConfig.Contexts["federal-context"] = context test := configCommandTest{ - args: []string{"set-context", "federal-context", "--" + clientcmd.FlagClusterName + "=clustername"}, + args: []string{"set-context", "federal-context", "--" + clientcmd.FlagNamespace + "=hammer"}, startingConfig: newRedFederalCowHammerConfig(), expectedConfig: expectedConfig, } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/config/create_authinfo.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/config/create_authinfo.go index 813390d177f5..814988bfb1a3 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/config/create_authinfo.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/config/create_authinfo.go @@ -25,26 +25,29 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd" clientcmdapi "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" ) type createAuthInfoOptions struct { pathOptions *pathOptions name string - authPath string - clientCertificate string - clientKey string - token string + authPath util.StringFlag + clientCertificate util.StringFlag + clientKey util.StringFlag + token util.StringFlag } func NewCmdConfigSetAuthInfo(out io.Writer, pathOptions *pathOptions) *cobra.Command { options := &createAuthInfoOptions{pathOptions: pathOptions} cmd := &cobra.Command{ - Use: "set-credentials name", + Use: fmt.Sprintf("set-credentials name [--%v=path/to/auth/file] [--%v=path/to/certficate/file] [--%v=path/to/key/file] [--%v=bearer_token_string]", clientcmd.FlagAuthPath, clientcmd.FlagCertFile, clientcmd.FlagKeyFile, clientcmd.FlagBearerToken), Short: "Sets a user entry in .kubeconfig", Long: `Sets a user entry in .kubeconfig - - Specifying a name that already exists overwrites that user entry. + Specifying a name that already exists will merge new fields on top of existing values for those fields. + e.g. + kubectl config set-credentials cluster-admin --client-key=~/.kube/cluster-admin/.kubecfg.key + only sets the client-key field on the cluster-admin user entry without touching other values. `, Run: func(cmd *cobra.Command, args []string) { if !options.complete(cmd) { @@ -58,10 +61,10 @@ func NewCmdConfigSetAuthInfo(out io.Writer, pathOptions *pathOptions) *cobra.Com }, } - cmd.Flags().StringVar(&options.authPath, clientcmd.FlagAuthPath, "", clientcmd.FlagAuthPath+" for the user entry in .kubeconfig") - cmd.Flags().StringVar(&options.clientCertificate, clientcmd.FlagCertFile, "", clientcmd.FlagCertFile+" for the user entry in .kubeconfig") - cmd.Flags().StringVar(&options.clientKey, clientcmd.FlagKeyFile, "", clientcmd.FlagKeyFile+" for the user entry in .kubeconfig") - cmd.Flags().StringVar(&options.token, clientcmd.FlagBearerToken, "", clientcmd.FlagBearerToken+" for the user entry in .kubeconfig") + cmd.Flags().Var(&options.authPath, clientcmd.FlagAuthPath, clientcmd.FlagAuthPath+" for the user entry in .kubeconfig") + cmd.Flags().Var(&options.clientCertificate, clientcmd.FlagCertFile, clientcmd.FlagCertFile+" for the user entry in .kubeconfig") + cmd.Flags().Var(&options.clientKey, clientcmd.FlagKeyFile, clientcmd.FlagKeyFile+" for the user entry in .kubeconfig") + cmd.Flags().Var(&options.token, clientcmd.FlagBearerToken, clientcmd.FlagBearerToken+" for the user entry in .kubeconfig") return cmd } @@ -77,7 +80,7 @@ func (o createAuthInfoOptions) run() error { return err } - authInfo := o.authInfo() + authInfo := o.modifyAuthInfo(config.AuthInfos[o.name]) config.AuthInfos[o.name] = authInfo err = clientcmd.WriteToFile(*config, filename) @@ -89,15 +92,23 @@ func (o createAuthInfoOptions) run() error { } // authInfo builds an AuthInfo object from the options -func (o *createAuthInfoOptions) authInfo() clientcmdapi.AuthInfo { - authInfo := clientcmdapi.AuthInfo{ - AuthPath: o.authPath, - ClientCertificate: o.clientCertificate, - ClientKey: o.clientKey, - Token: o.token, +func (o *createAuthInfoOptions) modifyAuthInfo(existingAuthInfo clientcmdapi.AuthInfo) clientcmdapi.AuthInfo { + modifiedAuthInfo := existingAuthInfo + + if o.authPath.Provided() { + modifiedAuthInfo.AuthPath = o.authPath.Value() + } + if o.clientCertificate.Provided() { + modifiedAuthInfo.ClientCertificate = o.clientCertificate.Value() + } + if o.clientKey.Provided() { + modifiedAuthInfo.ClientKey = o.clientKey.Value() + } + if o.token.Provided() { + modifiedAuthInfo.Token = o.token.Value() } - return authInfo + return modifiedAuthInfo } func (o *createAuthInfoOptions) complete(cmd *cobra.Command) bool { diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/config/create_cluster.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/config/create_cluster.go index ee9b49b3a26c..933aafb36026 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/config/create_cluster.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/config/create_cluster.go @@ -25,26 +25,29 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd" clientcmdapi "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" ) type createClusterOptions struct { pathOptions *pathOptions name string - server string - apiVersion string - insecureSkipTLSVerify bool - certificateAuthority string + server util.StringFlag + apiVersion util.StringFlag + insecureSkipTLSVerify util.BoolFlag + certificateAuthority util.StringFlag } func NewCmdConfigSetCluster(out io.Writer, pathOptions *pathOptions) *cobra.Command { options := &createClusterOptions{pathOptions: pathOptions} cmd := &cobra.Command{ - Use: "set-cluster name [server] [insecure-skip-tls-verify] [certificate-authority] [api-version]", + Use: fmt.Sprintf("set-cluster name [--%v=server] [--%v=path/to/certficate/authority] [--%v=apiversion] [--%v=true]", clientcmd.FlagAPIServer, clientcmd.FlagCAFile, clientcmd.FlagAPIVersion, clientcmd.FlagInsecure), Short: "Sets a cluster entry in .kubeconfig", Long: `Sets a cluster entry in .kubeconfig - - Specifying a name that already exists overwrites that cluster entry. + Specifying a name that already exists will merge new fields on top of existing values for those fields. + e.g. + kubectl config set-cluster e2e --certificate-authority=~/.kube/e2e/.kubernetes.ca.cert + only sets the certificate-authority field on the e2e cluster entry without touching other values. `, Run: func(cmd *cobra.Command, args []string) { if !options.complete(cmd) { @@ -58,10 +61,12 @@ func NewCmdConfigSetCluster(out io.Writer, pathOptions *pathOptions) *cobra.Comm }, } - cmd.Flags().StringVar(&options.server, clientcmd.FlagAPIServer, "", clientcmd.FlagAPIServer+" for the cluster entry in .kubeconfig") - cmd.Flags().StringVar(&options.apiVersion, clientcmd.FlagAPIVersion, "", clientcmd.FlagAPIVersion+" for the cluster entry in .kubeconfig") - cmd.Flags().BoolVar(&options.insecureSkipTLSVerify, clientcmd.FlagInsecure, false, clientcmd.FlagInsecure+" for the cluster entry in .kubeconfig") - cmd.Flags().StringVar(&options.certificateAuthority, clientcmd.FlagCAFile, "", clientcmd.FlagCAFile+" for the cluster entry in .kubeconfig") + options.insecureSkipTLSVerify.Default(false) + + cmd.Flags().Var(&options.server, clientcmd.FlagAPIServer, clientcmd.FlagAPIServer+" for the cluster entry in .kubeconfig") + cmd.Flags().Var(&options.apiVersion, clientcmd.FlagAPIVersion, clientcmd.FlagAPIVersion+" for the cluster entry in .kubeconfig") + cmd.Flags().Var(&options.insecureSkipTLSVerify, clientcmd.FlagInsecure, clientcmd.FlagInsecure+" for the cluster entry in .kubeconfig") + cmd.Flags().Var(&options.certificateAuthority, clientcmd.FlagCAFile, clientcmd.FlagCAFile+" for the cluster entry in .kubeconfig") return cmd } @@ -81,7 +86,7 @@ func (o createClusterOptions) run() error { config.Clusters = make(map[string]clientcmdapi.Cluster) } - cluster := o.cluster() + cluster := o.modifyCluster(config.Clusters[o.name]) config.Clusters[o.name] = cluster err = clientcmd.WriteToFile(*config, filename) @@ -93,15 +98,23 @@ func (o createClusterOptions) run() error { } // cluster builds a Cluster object from the options -func (o *createClusterOptions) cluster() clientcmdapi.Cluster { - cluster := clientcmdapi.Cluster{ - Server: o.server, - APIVersion: o.apiVersion, - InsecureSkipTLSVerify: o.insecureSkipTLSVerify, - CertificateAuthority: o.certificateAuthority, +func (o *createClusterOptions) modifyCluster(existingCluster clientcmdapi.Cluster) clientcmdapi.Cluster { + modifiedCluster := existingCluster + + if o.server.Provided() { + modifiedCluster.Server = o.server.Value() + } + if o.apiVersion.Provided() { + modifiedCluster.APIVersion = o.apiVersion.Value() + } + if o.insecureSkipTLSVerify.Provided() { + modifiedCluster.InsecureSkipTLSVerify = o.insecureSkipTLSVerify.Value() + } + if o.certificateAuthority.Provided() { + modifiedCluster.CertificateAuthority = o.certificateAuthority.Value() } - return cluster + return modifiedCluster } func (o *createClusterOptions) complete(cmd *cobra.Command) bool { diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/config/create_context.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/config/create_context.go index c77fba7c0f3f..2da9b859c916 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/config/create_context.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/config/create_context.go @@ -25,26 +25,30 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd" clientcmdapi "github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" ) type createContextOptions struct { pathOptions *pathOptions name string - cluster string - authInfo string - namespace string + cluster util.StringFlag + authInfo util.StringFlag + namespace util.StringFlag } func NewCmdConfigSetContext(out io.Writer, pathOptions *pathOptions) *cobra.Command { options := &createContextOptions{pathOptions: pathOptions} cmd := &cobra.Command{ - Use: "set-context name", + Use: fmt.Sprintf("set-context name [--%v=cluster-nickname] [--%v=user-nickname] [--%v=namespace]", clientcmd.FlagClusterName, clientcmd.FlagAuthInfoName, clientcmd.FlagNamespace), Short: "Sets a context entry in .kubeconfig", Long: `Sets a context entry in .kubeconfig - - Specifying a name that already exists overwrites that context entry. + Specifying a name that already exists will merge new fields on top of existing values for those fields. + e.g. + kubectl config set-context gce --user=cluster-admin + only sets the user field on the gce context entry without touching other values. `, + Run: func(cmd *cobra.Command, args []string) { if !options.complete(cmd) { return @@ -57,9 +61,9 @@ func NewCmdConfigSetContext(out io.Writer, pathOptions *pathOptions) *cobra.Comm }, } - cmd.Flags().StringVar(&options.cluster, clientcmd.FlagClusterName, "", clientcmd.FlagClusterName+" for the context entry in .kubeconfig") - cmd.Flags().StringVar(&options.authInfo, clientcmd.FlagAuthInfoName, "", clientcmd.FlagAuthInfoName+" for the context entry in .kubeconfig") - cmd.Flags().StringVar(&options.namespace, clientcmd.FlagNamespace, "", clientcmd.FlagNamespace+" for the context entry in .kubeconfig") + cmd.Flags().Var(&options.cluster, clientcmd.FlagClusterName, clientcmd.FlagClusterName+" for the context entry in .kubeconfig") + cmd.Flags().Var(&options.authInfo, clientcmd.FlagAuthInfoName, clientcmd.FlagAuthInfoName+" for the context entry in .kubeconfig") + cmd.Flags().Var(&options.namespace, clientcmd.FlagNamespace, clientcmd.FlagNamespace+" for the context entry in .kubeconfig") return cmd } @@ -75,7 +79,7 @@ func (o createContextOptions) run() error { return err } - context := o.context() + context := o.modifyContext(config.Contexts[o.name]) config.Contexts[o.name] = context err = clientcmd.WriteToFile(*config, filename) @@ -86,14 +90,20 @@ func (o createContextOptions) run() error { return nil } -func (o *createContextOptions) context() clientcmdapi.Context { - context := clientcmdapi.Context{ - Cluster: o.cluster, - AuthInfo: o.authInfo, - Namespace: o.namespace, +func (o *createContextOptions) modifyContext(existingContext clientcmdapi.Context) clientcmdapi.Context { + modifiedContext := existingContext + + if o.cluster.Provided() { + modifiedContext.Cluster = o.cluster.Value() + } + if o.authInfo.Provided() { + modifiedContext.AuthInfo = o.authInfo.Value() + } + if o.namespace.Provided() { + modifiedContext.Namespace = o.namespace.Value() } - return context + return modifiedContext } func (o *createContextOptions) complete(cmd *cobra.Command) bool { diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/create_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/create_test.go index 2253b9f74b00..c7a79c5c2b4b 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/create_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/create_test.go @@ -114,7 +114,7 @@ func TestCreateDirectory(t *testing.T) { cmd.Flags().Set("filename", "../../../examples/guestbook") cmd.Run(cmd, []string{}) - if buf.String() != "frontendController\nfrontend\nredis-master\nredis-master\nredisSlaveController\nredisslave\n" { + if buf.String() != "frontend-controller\nfrontend\nredis-master\nredis-master\nredis-slave-controller\nredisslave\n" { t.Errorf("unexpected output: %s", buf.String()) } } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/delete_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/delete_test.go index 3885d2f9fdd0..7fad141e7bf7 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/delete_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/delete_test.go @@ -206,7 +206,7 @@ func TestDeleteDirectory(t *testing.T) { cmd.Flags().Set("filename", "../../../examples/guestbook") cmd.Run(cmd, []string{}) - if buf.String() != "frontendController\nfrontend\nredis-master\nredis-master\nredisSlaveController\nredisslave\n" { + if buf.String() != "frontend-controller\nfrontend\nredis-master\nredis-master\nredis-slave-controller\nredisslave\n" { t.Errorf("unexpected output: %s", buf.String()) } } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/proxy.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/proxy.go index f99f2bcee3c3..920562a62ea7 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/proxy.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/proxy.go @@ -36,9 +36,9 @@ func (f *Factory) NewCmdProxy(out io.Writer) *cobra.Command { clientConfig, err := f.ClientConfig(cmd) checkErr(err) - server, err := kubectl.NewProxyServer(GetFlagString(cmd, "www"), clientConfig, port) + server, err := kubectl.NewProxyServer(GetFlagString(cmd, "www"), clientConfig) checkErr(err) - glog.Fatal(server.Serve()) + glog.Fatal(server.Serve(port)) }, } cmd.Flags().StringP("www", "w", "", "Also serve static files from the given directory under the prefix /static") diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/describe.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/describe.go index 3ebb5ca9ccbd..72baad1efda4 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/describe.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/describe.go @@ -47,10 +47,102 @@ func DescriberFor(kind string, c *client.Client) (Describer, bool) { return &ServiceDescriber{c}, true case "Minion", "Node": return &MinionDescriber{c}, true + case "LimitRange": + return &LimitRangeDescriber{c}, true + case "ResourceQuota": + return &ResourceQuotaDescriber{c}, true } return nil, false } +// LimitRangeDescriber generates information about a limit range +type LimitRangeDescriber struct { + client.Interface +} + +func (d *LimitRangeDescriber) Describe(namespace, name string) (string, error) { + lr := d.LimitRanges(namespace) + + limitRange, err := lr.Get(name) + if err != nil { + return "", err + } + + return tabbedString(func(out io.Writer) error { + fmt.Fprintf(out, "Name:\t%s\n", limitRange.Name) + fmt.Fprintf(out, "Type\tResource\tMin\tMax\n") + fmt.Fprintf(out, "----\t--------\t---\t---\n") + for i := range limitRange.Spec.Limits { + item := limitRange.Spec.Limits[i] + maxResources := item.Max + minResources := item.Min + + set := map[api.ResourceName]bool{} + for k := range maxResources { + set[k] = true + } + for k := range minResources { + set[k] = true + } + + for k := range set { + // if no value is set, we output - + maxValue := "-" + minValue := "-" + + maxQuantity, maxQuantityFound := maxResources[k] + if maxQuantityFound { + maxValue = maxQuantity.String() + } + + minQuantity, minQuantityFound := minResources[k] + if minQuantityFound { + minValue = minQuantity.String() + } + + msg := "%v\t%v\t%v\t%v\n" + fmt.Fprintf(out, msg, item.Type, k, minValue, maxValue) + } + } + return nil + }) +} + +// ResourceQuotaDescriber generates information about a resource quota +type ResourceQuotaDescriber struct { + client.Interface +} + +func (d *ResourceQuotaDescriber) Describe(namespace, name string) (string, error) { + rq := d.ResourceQuotas(namespace) + + resourceQuota, err := rq.Get(name) + if err != nil { + return "", err + } + + return tabbedString(func(out io.Writer) error { + fmt.Fprintf(out, "Name:\t%s\n", resourceQuota.Name) + fmt.Fprintf(out, "Resource\tUsed\tHard\n") + fmt.Fprintf(out, "--------\t----\t----\n") + + resources := []api.ResourceName{} + for resource := range resourceQuota.Status.Hard { + resources = append(resources, resource) + } + sort.Sort(SortableResourceNames(resources)) + + msg := "%v\t%v\t%v\n" + for i := range resources { + resource := resources[i] + hardQuantity := resourceQuota.Status.Hard[resource] + usedQuantity := resourceQuota.Status.Used[resource] + fmt.Fprintf(out, msg, resource, usedQuantity.String(), hardQuantity.String()) + } + return nil + }) +} + // PodDescriber generates information about a pod and the replication controllers that // create it. type PodDescriber struct { @@ -202,7 +294,7 @@ func describeEvents(el *api.EventList, w io.Writer) { sort.Sort(SortableEvents(el.Items)) fmt.Fprint(w, "Events:\nTime\tFrom\tSubobjectPath\tReason\tMessage\n") for _, e := range el.Items { - fmt.Fprintf(w, "%s\t%v\t%v\t%v\t%v\t%v\n", + fmt.Fprintf(w, "%s\t%v\t%v\t%v\t%v\n", e.Timestamp.Time.Format(time.RFC1123Z), e.Source, e.InvolvedObject.FieldPath, diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/kubectl.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/kubectl.go index 07530b4ef256..517ff7ddf35a 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/kubectl.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/kubectl.go @@ -143,11 +143,13 @@ func (e ShortcutExpander) VersionAndKindForResource(resource string) (defaultVer // indeed a shortcut. Otherwise, will return resource unmodified. func expandResourceShortcut(resource string) string { shortForms := map[string]string{ - "po": "pods", - "rc": "replicationcontrollers", - "se": "services", - "mi": "minions", - "ev": "events", + "po": "pods", + "rc": "replicationcontrollers", + "se": "services", + "mi": "minions", + "ev": "events", + "limits": "limitRanges", + "quota": "resourceQuotas", } if expanded, ok := shortForms[resource]; ok { return expanded diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/proxy_server.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/proxy_server.go index 19833a90ce36..a92e0485c4f2 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/proxy_server.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/proxy_server.go @@ -29,12 +29,11 @@ import ( // ProxyServer is a http.Handler which proxies Kubernetes APIs to remote API server. type ProxyServer struct { httputil.ReverseProxy - Port int } // NewProxyServer creates and installs a new ProxyServer. // It automatically registers the created ProxyServer to http.DefaultServeMux. -func NewProxyServer(filebase string, cfg *client.Config, port int) (*ProxyServer, error) { +func NewProxyServer(filebase string, cfg *client.Config) (*ProxyServer, error) { prefix := cfg.Prefix if prefix == "" { prefix = "/api" @@ -52,9 +51,9 @@ func NewProxyServer(filebase string, cfg *client.Config, port int) (*ProxyServer return proxy, nil } -// Serve starts the server (http.DefaultServeMux) on TCP port 8001, loops forever. -func (s *ProxyServer) Serve() error { - addr := fmt.Sprintf(":%d", s.Port) +// Serve starts the server (http.DefaultServeMux) on given port, loops forever. +func (s *ProxyServer) Serve(port int) error { + addr := fmt.Sprintf(":%d", port) return http.ListenAndServe(addr, nil) } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource_printer.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource_printer.go index 79321044a55b..5b0775e9b35a 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource_printer.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource_printer.go @@ -221,6 +221,8 @@ var serviceColumns = []string{"NAME", "LABELS", "SELECTOR", "IP", "PORT"} var minionColumns = []string{"NAME", "LABELS", "STATUS"} var statusColumns = []string{"STATUS"} var eventColumns = []string{"TIME", "NAME", "KIND", "SUBOBJECT", "REASON", "SOURCE", "MESSAGE"} +var limitRangeColumns = []string{"NAME"} +var resourceQuotaColumns = []string{"NAME"} // addDefaultHandlers adds print handlers for default Kubernetes types. func (h *HumanReadablePrinter) addDefaultHandlers() { @@ -235,6 +237,10 @@ func (h *HumanReadablePrinter) addDefaultHandlers() { h.Handler(statusColumns, printStatus) h.Handler(eventColumns, printEvent) h.Handler(eventColumns, printEventList) + h.Handler(limitRangeColumns, printLimitRange) + h.Handler(limitRangeColumns, printLimitRangeList) + h.Handler(resourceQuotaColumns, printResourceQuota) + h.Handler(resourceQuotaColumns, printResourceQuotaList) } func (h *HumanReadablePrinter) unknown(data []byte, w io.Writer) error { @@ -409,6 +415,42 @@ func printEventList(list *api.EventList, w io.Writer) error { return nil } +func printLimitRange(limitRange *api.LimitRange, w io.Writer) error { + _, err := fmt.Fprintf( + w, "%s\n", + limitRange.Name, + ) + return err +} + +// Prints the LimitRangeList in a human-friendly format. +func printLimitRangeList(list *api.LimitRangeList, w io.Writer) error { + for i := range list.Items { + if err := printLimitRange(&list.Items[i], w); err != nil { + return err + } + } + return nil +} + +func printResourceQuota(resourceQuota *api.ResourceQuota, w io.Writer) error { + _, err := fmt.Fprintf( + w, "%s\n", + resourceQuota.Name, + ) + return err +} + +// Prints the ResourceQuotaList in a human-friendly format. +func printResourceQuotaList(list *api.ResourceQuotaList, w io.Writer) error { + for i := range list.Items { + if err := printResourceQuota(&list.Items[i], w); err != nil { + return err + } + } + return nil +} + // PrintObj prints the obj in a human-friendly format according to the type of the obj. func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) error { w := tabwriter.NewWriter(output, 20, 5, 3, ' ', 0) diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource_printer_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource_printer_test.go index b33e5d60bfe6..03b8b860b21c 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource_printer_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource_printer_test.go @@ -305,7 +305,7 @@ func TestTemplateEmitsVersionedObjects(t *testing.T) { } func TestTemplatePanic(t *testing.T) { - tmpl := `{{and ((index .currentState.info "update-demo").state.running.startedAt) .currentState.info.net.state.running.startedAt}}` + tmpl := `{{and ((index .currentState.info "foo").state.running.startedAt) .currentState.info.net.state.running.startedAt}}` printer, err := NewTemplatePrinter([]byte(tmpl)) if err != nil { t.Fatalf("tmpl fail: %v", err) @@ -328,18 +328,18 @@ func TestTemplateStrings(t *testing.T) { }{ "nilInfo": {api.Pod{}, "false"}, "emptyInfo": {api.Pod{Status: api.PodStatus{Info: api.PodInfo{}}}, "false"}, - "containerExists": { + "fooExists": { api.Pod{ Status: api.PodStatus{ - Info: api.PodInfo{"update-demo": api.ContainerStatus{}}, + Info: api.PodInfo{"foo": api.ContainerStatus{}}, }, }, "false", }, - "netExists": { + "barExists": { api.Pod{ Status: api.PodStatus{ - Info: api.PodInfo{"net": api.ContainerStatus{}}, + Info: api.PodInfo{"bar": api.ContainerStatus{}}, }, }, "false", @@ -348,8 +348,8 @@ func TestTemplateStrings(t *testing.T) { api.Pod{ Status: api.PodStatus{ Info: api.PodInfo{ - "update-demo": api.ContainerStatus{}, - "net": api.ContainerStatus{}, + "foo": api.ContainerStatus{}, + "bar": api.ContainerStatus{}, }, }, }, @@ -359,8 +359,8 @@ func TestTemplateStrings(t *testing.T) { api.Pod{ Status: api.PodStatus{ Info: api.PodInfo{ - "update-demo": api.ContainerStatus{}, - "net": api.ContainerStatus{ + "foo": api.ContainerStatus{}, + "bar": api.ContainerStatus{ State: api.ContainerState{ Running: &api.ContainerStateRunning{ StartedAt: util.Time{}, @@ -376,14 +376,14 @@ func TestTemplateStrings(t *testing.T) { api.Pod{ Status: api.PodStatus{ Info: api.PodInfo{ - "update-demo": api.ContainerStatus{ + "foo": api.ContainerStatus{ State: api.ContainerState{ Running: &api.ContainerStateRunning{ StartedAt: util.Time{}, }, }, }, - "net": api.ContainerStatus{ + "bar": api.ContainerStatus{ State: api.ContainerState{ Running: &api.ContainerStateRunning{ StartedAt: util.Time{}, @@ -400,14 +400,14 @@ func TestTemplateStrings(t *testing.T) { // The point of this test is to verify that the below template works. If you change this // template, you need to update hack/e2e-suite/update.sh. tmpl := - `{{and (exists . "currentState" "info" "update-demo" "state" "running") (exists . "currentState" "info" "net" "state" "running")}}` + `{{and (exists . "currentState" "info" "foo" "state" "running") (exists . "currentState" "info" "bar" "state" "running")}}` useThisToDebug := ` a: {{exists . "currentState"}} b: {{exists . "currentState" "info"}} -c: {{exists . "currentState" "info" "update-demo"}} -d: {{exists . "currentState" "info" "update-demo" "state"}} -e: {{exists . "currentState" "info" "update-demo" "state" "running"}} -f: {{exists . "currentState" "info" "update-demo" "state" "running" "startedAt"}}` +c: {{exists . "currentState" "info" "foo"}} +d: {{exists . "currentState" "info" "foo" "state"}} +e: {{exists . "currentState" "info" "foo" "state" "running"}} +f: {{exists . "currentState" "info" "foo" "state" "running" "startedAt"}}` _ = useThisToDebug // don't complain about unused var p, err := NewTemplatePrinter([]byte(tmpl)) diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/sorted_event_list_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/sorted_event_list_test.go index 7307a8038ea9..116e386fd6fa 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/sorted_event_list_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/sorted_event_list_test.go @@ -17,12 +17,13 @@ limitations under the License. package kubectl import ( - "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "sort" "strings" "testing" "time" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" ) // VerifyDatesInOrder checks the start of each line for a RFC1123Z date diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/sorted_resource_name_list.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/sorted_resource_name_list.go new file mode 100644 index 000000000000..6e6a4fb602ba --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/sorted_resource_name_list.go @@ -0,0 +1,35 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 kubectl + +import ( + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" +) + +type SortableResourceNames []api.ResourceName + +func (list SortableResourceNames) Len() int { + return len(list) +} + +func (list SortableResourceNames) Swap(i, j int) { + list[i], list[j] = list[j], list[i] +} + +func (list SortableResourceNames) Less(i, j int) bool { + return list[i] < list[j] +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/config/apiserver.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/config/apiserver.go index 113a5ec800b3..5057ac9518f1 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/config/apiserver.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/config/apiserver.go @@ -53,5 +53,5 @@ func newSourceApiserverFromLW(lw cache.ListerWatcher, updates chan<- interface{} } updates <- kubelet.PodUpdate{bpods, kubelet.SET, kubelet.ApiserverSource} } - cache.NewReflector(lw, &api.Pod{}, cache.NewUndeltaStore(send)).Run() + cache.NewReflector(lw, &api.Pod{}, cache.NewUndeltaStore(send, cache.MetaNamespaceKeyFunc)).Run() } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/config/apiserver_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/config/apiserver_test.go index 936ff22aaecb..0fe5399c4de0 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/config/apiserver_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/config/apiserver_test.go @@ -139,6 +139,47 @@ func TestNewSourceApiserver_UpdatesAndMultiplePods(t *testing.T) { } } +func TestNewSourceApiserver_TwoNamespacesSameName(t *testing.T) { + pod1 := api.Pod{ + ObjectMeta: api.ObjectMeta{Name: "p", Namespace: "one"}, + Spec: api.PodSpec{Containers: []api.Container{{Image: "image/one"}}}} + pod2 := api.Pod{ + ObjectMeta: api.ObjectMeta{Name: "p", Namespace: "two"}, + Spec: api.PodSpec{Containers: []api.Container{{Image: "image/blah"}}}} + + // Setup fake api client. + fakeWatch := watch.NewFake() + lw := fakePodLW{ + listResp: &api.PodList{Items: []api.Pod{pod1, pod2}}, + watchResp: fakeWatch, + } + + ch := make(chan interface{}) + + newSourceApiserverFromLW(lw, ch) + + got, ok := <-ch + if !ok { + t.Errorf("Unable to read from channel when expected") + } + update := got.(kubelet.PodUpdate) + // Make sure that we get both pods. Catches bug #2294. + if !(len(update.Pods) == 2) { + t.Errorf("Expected %d, Got %d", 2, len(update.Pods)) + } + + // Delete pod1 + fakeWatch.Delete(&pod1) + got, ok = <-ch + if !ok { + t.Errorf("Unable to read from channel when expected") + } + update = got.(kubelet.PodUpdate) + if !(len(update.Pods) == 1) { + t.Errorf("Expected %d, Got %d", 1, len(update.Pods)) + } +} + func TestNewSourceApiserverInitialEmptySendsEmptyPodUpdate(t *testing.T) { // Setup fake api client. fakeWatch := watch.NewFake() diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/config/file_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/config/file_test.go index ade512aa7aad..c171f836bd14 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/config/file_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/config/file_test.go @@ -98,7 +98,7 @@ func TestUpdateOnNonExistentFile(t *testing.T) { t.Fatalf("Expected %#v, Got %#v", expected, update) } - case <-time.After(2 * time.Millisecond): + case <-time.After(time.Second): t.Errorf("Expected update, timeout instead") } } @@ -165,7 +165,7 @@ func TestReadFromFile(t *testing.T) { t.Fatalf("Expected %#v, Got %#v", expected, update) } - case <-time.After(2 * time.Millisecond): + case <-time.After(time.Second): t.Errorf("Expected update, timeout instead") } } @@ -213,7 +213,7 @@ func TestReadFromFileWithoutID(t *testing.T) { t.Fatalf("Expected %#v, Got %#v", expected, update) } - case <-time.After(2 * time.Millisecond): + case <-time.After(time.Second): t.Errorf("Expected update, timeout instead") } } @@ -258,7 +258,7 @@ func TestReadV1Beta2FromFile(t *testing.T) { t.Fatalf("Expected %#v, Got %#v", expected, update) } - case <-time.After(2 * time.Millisecond): + case <-time.After(time.Second): t.Errorf("Expected update, timeout instead") } } @@ -281,7 +281,7 @@ func TestReadFromFileWithDefaults(t *testing.T) { t.Errorf("Unexpected UID: %s", update.Pods[0].ObjectMeta.UID) } - case <-time.After(2 * time.Millisecond): + case <-time.After(time.Second): t.Errorf("Expected update, timeout instead") } } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools/docker.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools/docker.go index 4d3f9b2447a6..bb030743f772 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools/docker.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools/docker.go @@ -31,12 +31,17 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/credentialprovider" + "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/leaky" "github.com/GoogleCloudPlatform/kubernetes/pkg/types" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" docker "github.com/fsouza/go-dockerclient" "github.com/golang/glog" ) +const ( + PodInfraContainerName = leaky.PodInfraContainerName +) + // DockerInterface is an abstract interface for testability. It abstracts the interface of docker.Client. type DockerInterface interface { ListContainers(options docker.ListContainersOptions) ([]docker.APIContainers, error) @@ -240,7 +245,11 @@ func (p dockerPuller) IsImagePresent(image string) (bool, error) { // RequireLatestImage returns if the user wants the latest image func RequireLatestImage(name string) bool { - // REVERTED: Change behavior from upstream + _, tag := parseImageName(name) + + if tag == "latest" { + return true + } return false } @@ -368,8 +377,8 @@ var ( // ErrNoContainersInPod is returned when there are no containers for a given pod ErrNoContainersInPod = errors.New("no containers exist for this pod") - // ErrNoNetworkContainerInPod is returned when there is no network container for a given pod - ErrNoNetworkContainerInPod = errors.New("No network container exists for this pod") + // ErrNoPodInfraContainerInPod is returned when there is no pod infra container for a given pod + ErrNoPodInfraContainerInPod = errors.New("No pod infra container exists for this pod") // ErrContainerCannotRun is returned when a container is created, but cannot run properly ErrContainerCannotRun = errors.New("Container cannot run") @@ -397,7 +406,7 @@ func inspectContainer(client DockerInterface, dockerID, containerName, tPath str containerStatus.State.Running = &api.ContainerStateRunning{ StartedAt: util.NewTime(inspectResult.State.StartedAt), } - if containerName == "net" && inspectResult.NetworkSettings != nil { + if containerName == PodInfraContainerName && inspectResult.NetworkSettings != nil { containerStatus.PodIP = inspectResult.NetworkSettings.IPAddress } waiting = false @@ -450,7 +459,7 @@ func GetDockerPodInfo(client DockerInterface, manifest api.PodSpec, podFullName for _, container := range manifest.Containers { expectedContainers[container.Name] = container } - expectedContainers["net"] = api.Container{} + expectedContainers[PodInfraContainerName] = api.Container{} containers, err := client.ListContainers(docker.ListContainersOptions{All: true}) if err != nil { @@ -494,9 +503,9 @@ func GetDockerPodInfo(client DockerInterface, manifest api.PodSpec, podFullName return nil, ErrNoContainersInPod } - // First make sure we are not missing network container - if _, found := info["net"]; !found { - return nil, ErrNoNetworkContainerInPod + // First make sure we are not missing pod infra container + if _, found := info[PodInfraContainerName]; !found { + return nil, ErrNoPodInfraContainerInPod } if len(info) < (len(manifest.Containers) + 1) { diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools/docker_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools/docker_test.go index df1cf58c5392..8609036ae1bd 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools/docker_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools/docker_test.go @@ -262,6 +262,50 @@ func TestDockerKeyringLookup(t *testing.T) { } } +// This validates that dockercfg entries with a scheme and url path are properly matched +// by images that only match the hostname. +// NOTE: the above covers the case of a more specific match trumping just hostname. +func TestIssue3797(t *testing.T) { + rex := docker.AuthConfiguration{ + Username: "rex", + Password: "tiny arms", + Email: "rex@example.com", + } + + dk := &credentialprovider.BasicDockerKeyring{} + dk.Add(credentialprovider.DockerConfig{ + "https://quay.io/v1/": credentialprovider.DockerConfigEntry{ + Username: rex.Username, + Password: rex.Password, + Email: rex.Email, + }, + }) + + tests := []struct { + image string + match docker.AuthConfiguration + ok bool + }{ + // direct match + {"quay.io", rex, true}, + + // partial matches + {"quay.io/foo", rex, true}, + {"quay.io/foo/bar", rex, true}, + } + + for i, tt := range tests { + match, ok := dk.Lookup(tt.image) + if tt.ok != ok { + t.Errorf("case %d: expected ok=%t, got %t", i, tt.ok, ok) + } + + if !reflect.DeepEqual(tt.match, match) { + t.Errorf("case %d: expected match=%#v, got %#v", i, tt.match, match) + } + } +} + type imageTrackingDockerClient struct { *FakeDockerClient imageName string diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/handlers.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/handlers.go index 0e285660564f..c4cb0d70433f 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/handlers.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/handlers.go @@ -24,6 +24,7 @@ import ( "strconv" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools" "github.com/GoogleCloudPlatform/kubernetes/pkg/types" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/golang/glog" @@ -77,7 +78,7 @@ func (h *httpActionHandler) Run(podFullName string, uid types.UID, container *ap glog.Errorf("unable to get pod info, event handlers may be invalid.") return err } - netInfo, found := status.Info[networkContainerName] + netInfo, found := status.Info[dockertools.PodInfraContainerName] if found { host = netInfo.PodIP } else { diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/kubelet.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/kubelet.go index c2be5fe94b8f..a2a1f113d4b3 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/kubelet.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/kubelet.go @@ -36,11 +36,11 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache" "github.com/GoogleCloudPlatform/kubernetes/pkg/client/record" - "github.com/GoogleCloudPlatform/kubernetes/pkg/health" "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools" "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/envvars" "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/volume" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" + "github.com/GoogleCloudPlatform/kubernetes/pkg/probe" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/types" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" @@ -72,7 +72,7 @@ func NewMainKubelet( etcdClient tools.EtcdClient, kubeClient *client.Client, rootDirectory string, - networkContainerImage string, + podInfraContainerImage string, resyncInterval time.Duration, pullQPS float32, pullBurst int, @@ -93,7 +93,7 @@ func NewMainKubelet( return nil, fmt.Errorf("invalid minimum GC age %d", minimumGCAge) } - serviceStore := cache.NewStore() + serviceStore := cache.NewStore(cache.MetaNamespaceKeyFunc) if kubeClient != nil { cache.NewReflector(&cache.ListWatch{kubeClient, labels.Everything(), "services", api.NamespaceAll}, &api.Service{}, serviceStore).Run() } @@ -106,7 +106,7 @@ func NewMainKubelet( kubeClient: kubeClient, rootDirectory: rootDirectory, resyncInterval: resyncInterval, - networkContainerImage: networkContainerImage, + podInfraContainerImage: podInfraContainerImage, podWorkers: newPodWorkers(), dockerIDToRef: map[dockertools.DockerID]*api.ObjectReference{}, runner: dockertools.NewDockerContainerCommandRunner(dockerClient), @@ -142,15 +142,15 @@ type serviceLister interface { // Kubelet is the main kubelet implementation. type Kubelet struct { - hostname string - dockerClient dockertools.DockerInterface - kubeClient *client.Client - rootDirectory string - networkContainerImage string - podWorkers *podWorkers - resyncInterval time.Duration - pods []api.BoundPod - sourceReady SourceReadyFn + hostname string + dockerClient dockertools.DockerInterface + kubeClient *client.Client + rootDirectory string + podInfraContainerImage string + podWorkers *podWorkers + resyncInterval time.Duration + pods []api.BoundPod + sourceReady SourceReadyFn // Needed to report events for containers belonging to deleted/modified pods. // Tracks references for reporting events @@ -164,8 +164,6 @@ type Kubelet struct { // Optional, no events will be sent without it etcdClient tools.EtcdClient - // Optional, defaults to simple implementaiton - healthChecker health.HealthChecker // Optional, defaults to simple Docker implementation dockerPuller dockertools.DockerPuller // Optional, defaults to /logs/ from /var/log @@ -427,9 +425,6 @@ func (kl *Kubelet) Run(updates <-chan PodUpdate) { if kl.dockerPuller == nil { kl.dockerPuller = dockertools.NewDockerPuller(kl.dockerClient, kl.pullQPS, kl.pullBurst) } - if kl.healthChecker == nil { - kl.healthChecker = health.NewHealthChecker() - } kl.syncLoop(updates, kl) } @@ -532,6 +527,20 @@ func milliCPUToShares(milliCPU int64) int64 { return shares } +func makeCapabilites(capAdd []api.CapabilityType, capDrop []api.CapabilityType) ([]string, []string) { + var ( + addCaps []string + dropCaps []string + ) + for _, cap := range capAdd { + addCaps = append(addCaps, string(cap)) + } + for _, cap := range capDrop { + dropCaps = append(dropCaps, string(cap)) + } + return addCaps, dropCaps +} + // A basic interface that knows how to execute handlers type actionHandler interface { Run(podFullName string, uid types.UID, container *api.Container, handler *api.Handler) error @@ -583,7 +592,7 @@ func containerRef(pod *api.BoundPod, container *api.Container) (*api.ObjectRefer fieldPath, err := fieldPath(pod, container) if err != nil { // TODO: figure out intelligent way to refer to containers that we implicitly - // start (like the network container). This is not a good way, ugh. + // start (like the pod infra container). This is not a good way, ugh. fieldPath = "implicitly required container " + container.Name } ref, err := api.GetPartialReference(pod, fieldPath) @@ -619,7 +628,7 @@ func (kl *Kubelet) getRef(id dockertools.DockerID) (ref *api.ObjectReference, ok } // Run a single container from a pod. Returns the docker container ID -func (kl *Kubelet) runContainer(pod *api.BoundPod, container *api.Container, podVolumes volumeMap, netMode string) (id dockertools.DockerID, err error) { +func (kl *Kubelet) runContainer(pod *api.BoundPod, container *api.Container, podVolumes volumeMap, netMode, ipcMode string) (id dockertools.DockerID, err error) { ref, err := containerRef(pod, container) if err != nil { glog.Errorf("Couldn't make a ref to pod %v, container %v: '%v'", pod.Name, container.Name, err) @@ -680,11 +689,16 @@ func (kl *Kubelet) runContainer(pod *api.BoundPod, container *api.Container, pod } else if container.Privileged { return "", fmt.Errorf("container requested privileged mode, but it is disallowed globally.") } + + capAdd, capDrop := makeCapabilites(container.Capabilities.Add, container.Capabilities.Drop) hc := &docker.HostConfig{ PortBindings: portBindings, Binds: binds, NetworkMode: netMode, + IpcMode: ipcMode, Privileged: privileged, + CapAdd: capAdd, + CapDrop: capDrop, } if pod.Spec.DNSPolicy == api.DNSClusterFirst { if err := kl.applyClusterDNS(hc, pod); err != nil { @@ -739,7 +753,7 @@ func (kl *Kubelet) getServiceEnvVarMap(ns string) (map[string]string, error) { switch service.Namespace { // for the case whether the master service namespace is the namespace the pod - // is in, pod should receive all the pods in the namespace. + // is in, the pod should receive all the services in the namespace. // // ordering of the case clauses below enforces this case ns: @@ -878,21 +892,20 @@ func (kl *Kubelet) killContainerByID(ID, name string) error { } const ( - networkContainerName = "net" - NetworkContainerImage = "kubernetes/pause:latest" + PodInfraContainerImage = "kubernetes/pause:latest" ) -// createNetworkContainer starts the network container for a pod. Returns the docker container ID of the newly created container. -func (kl *Kubelet) createNetworkContainer(pod *api.BoundPod) (dockertools.DockerID, error) { +// createPodInfraContainer starts the pod infra container for a pod. Returns the docker container ID of the newly created container. +func (kl *Kubelet) createPodInfraContainer(pod *api.BoundPod) (dockertools.DockerID, error) { var ports []api.Port - // Docker only exports ports from the network container. Let's + // Docker only exports ports from the pod infra container. Let's // collect all of the relevant ports and export them. for _, container := range pod.Spec.Containers { ports = append(ports, container.Ports...) } container := &api.Container{ - Name: networkContainerName, - Image: kl.networkContainerImage, + Name: dockertools.PodInfraContainerName, + Image: kl.podInfraContainerImage, Ports: ports, } ref, err := containerRef(pod, container) @@ -915,7 +928,7 @@ func (kl *Kubelet) createNetworkContainer(pod *api.BoundPod) (dockertools.Docker if ref != nil { record.Eventf(ref, "pulled", "Successfully pulled image %q", container.Image) } - return kl.runContainer(pod, container, nil, "") + return kl.runContainer(pod, container, nil, "", "") } func (kl *Kubelet) pullImage(img string, ref *api.ObjectReference) error { @@ -987,19 +1000,19 @@ func (kl *Kubelet) syncPod(pod *api.BoundPod, dockerContainers dockertools.Docke return err } - // Make sure we have a network container - var netID dockertools.DockerID - if netDockerContainer, found, _ := dockerContainers.FindPodContainer(podFullName, uid, networkContainerName); found { - netID = dockertools.DockerID(netDockerContainer.ID) + // Make sure we have a pod infra container + var podInfraContainerID dockertools.DockerID + if podInfraDockerContainer, found, _ := dockerContainers.FindPodContainer(podFullName, uid, dockertools.PodInfraContainerName); found { + podInfraContainerID = dockertools.DockerID(podInfraDockerContainer.ID) } else { - glog.V(2).Infof("Network container doesn't exist for pod %q, killing and re-creating the pod", podFullName) + glog.V(2).Infof("Pod infra container doesn't exist for pod %q, killing and re-creating the pod", podFullName) count, err := kl.killContainersInPod(pod, dockerContainers) if err != nil { return err } - netID, err = kl.createNetworkContainer(pod) + podInfraContainerID, err = kl.createPodInfraContainer(pod) if err != nil { - glog.Errorf("Failed to introspect network container: %v; Skipping pod %q", err, podFullName) + glog.Errorf("Failed to introspect pod infra container: %v; Skipping pod %q", err, podFullName) return err } if count > 0 { @@ -1011,7 +1024,7 @@ func (kl *Kubelet) syncPod(pod *api.BoundPod, dockerContainers dockertools.Docke } } } - containersToKeep[netID] = empty{} + containersToKeep[podInfraContainerID] = empty{} podVolumes, err := kl.mountExternalVolumes(pod) if err != nil { @@ -1023,7 +1036,7 @@ func (kl *Kubelet) syncPod(pod *api.BoundPod, dockerContainers dockertools.Docke if err != nil { glog.Errorf("Unable to get pod with name %q and uid %q info, health checks may be invalid", podFullName, uid) } - netInfo, found := podStatus.Info[networkContainerName] + netInfo, found := podStatus.Info[dockertools.PodInfraContainerName] if found { podStatus.PodIP = netInfo.PodIP } @@ -1038,13 +1051,13 @@ func (kl *Kubelet) syncPod(pod *api.BoundPod, dockerContainers dockertools.Docke // look for changes in the container. if hash == 0 || hash == expectedHash { // TODO: This should probably be separated out into a separate goroutine. - healthy, err := kl.healthy(podFullName, uid, podStatus, container, dockerContainer) + healthy, err := kl.probeLiveness(podFullName, uid, podStatus, container, dockerContainer) if err != nil { glog.V(1).Infof("health check errored: %v", err) containersToKeep[containerID] = empty{} continue } - if healthy == health.Healthy { + if healthy == probe.Success { containersToKeep[containerID] = empty{} continue } @@ -1058,10 +1071,10 @@ func (kl *Kubelet) syncPod(pod *api.BoundPod, dockerContainers dockertools.Docke } killedContainers[containerID] = empty{} - // Also kill associated network container - if netContainer, found, _ := dockerContainers.FindPodContainer(podFullName, uid, networkContainerName); found { - if err := kl.killContainer(netContainer); err != nil { - glog.V(1).Infof("Failed to kill network container %q: %v", netContainer.ID, err) + // Also kill associated pod infra container + if podInfraContainer, found, _ := dockerContainers.FindPodContainer(podFullName, uid, dockertools.PodInfraContainerName); found { + if err := kl.killContainer(podInfraContainer); err != nil { + glog.V(1).Infof("Failed to kill pod infra container %q: %v", podInfraContainer.ID, err) continue } } @@ -1112,7 +1125,8 @@ func (kl *Kubelet) syncPod(pod *api.BoundPod, dockerContainers dockertools.Docke } } // TODO(dawnchen): Check RestartPolicy.DelaySeconds before restart a container - containerID, err := kl.runContainer(pod, &container, podVolumes, "container:"+string(netID)) + namespaceMode := fmt.Sprintf("container:%v", podInfraContainerID) + containerID, err := kl.runContainer(pod, &container, podVolumes, namespaceMode, namespaceMode) if err != nil { // TODO(bburns) : Perhaps blacklist a container after N failures? glog.Errorf("Error running pod %q container %q: %v", podFullName, container.Name, err) @@ -1222,7 +1236,7 @@ func (kl *Kubelet) SyncPods(pods []api.BoundPod) error { desiredPods[uid] = empty{} // Add all containers (including net) to the map. - desiredContainers[podContainer{podFullName, uid, networkContainerName}] = empty{} + desiredContainers[podContainer{podFullName, uid, dockertools.PodInfraContainerName}] = empty{} for _, cont := range pod.Spec.Containers { desiredContainers[podContainer{podFullName, uid, cont.Name}] = empty{} } @@ -1403,18 +1417,15 @@ func (kl *Kubelet) GetPodStatus(podFullName string, uid types.UID) (api.PodStatu return podStatus, err } -func (kl *Kubelet) healthy(podFullName string, podUID types.UID, status api.PodStatus, container api.Container, dockerContainer *docker.APIContainers) (health.Status, error) { +func (kl *Kubelet) probeLiveness(podFullName string, podUID types.UID, status api.PodStatus, container api.Container, dockerContainer *docker.APIContainers) (probe.Status, error) { // Give the container 60 seconds to start up. if container.LivenessProbe == nil { - return health.Healthy, nil + return probe.Success, nil } if time.Now().Unix()-dockerContainer.Created < container.LivenessProbe.InitialDelaySeconds { - return health.Healthy, nil - } - if kl.healthChecker == nil { - return health.Healthy, nil + return probe.Success, nil } - return kl.healthChecker.HealthCheck(podFullName, podUID, status, container) + return kl.probeContainer(container.LivenessProbe, podFullName, podUID, status, container) } // Returns logs of current machine. diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/kubelet_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/kubelet_test.go index 3c1811359896..b3b44cb4c496 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/kubelet_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/kubelet_test.go @@ -31,7 +31,6 @@ import ( "time" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - "github.com/GoogleCloudPlatform/kubernetes/pkg/health" "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools" "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/volume" _ "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/volume/host_path" @@ -336,8 +335,8 @@ func TestSyncPodsDoesNothing(t *testing.T) { ID: "1234", }, { - // network container - Names: []string{"/k8s_net_foo.new.test_12345678_0"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.test_12345678_0"}, ID: "9876", }, } @@ -426,7 +425,7 @@ func matchString(t *testing.T, pattern, str string) bool { func TestSyncPodsCreatesNetAndContainer(t *testing.T) { kubelet, fakeDocker := newTestKubelet(t) - kubelet.networkContainerImage = "custom_image_name" + kubelet.podInfraContainerImage = "custom_image_name" fakeDocker.ContainerList = []docker.APIContainers{} err := kubelet.SyncPods([]api.BoundPod{ { @@ -455,16 +454,16 @@ func TestSyncPodsCreatesNetAndContainer(t *testing.T) { found := false for _, c := range fakeDocker.ContainerList { - if c.Image == "custom_image_name" && strings.HasPrefix(c.Names[0], "/k8s_net") { + if c.Image == "custom_image_name" && strings.HasPrefix(c.Names[0], "/k8s_POD") { found = true } } if !found { - t.Errorf("Custom net container not found: %v", fakeDocker.ContainerList) + t.Errorf("Custom pod infra container not found: %v", fakeDocker.ContainerList) } if len(fakeDocker.Created) != 2 || - !matchString(t, "k8s_net\\.[a-f0-9]+_foo.new.test_", fakeDocker.Created[0]) || + !matchString(t, "k8s_POD\\.[a-f0-9]+_foo.new.test_", fakeDocker.Created[0]) || !matchString(t, "k8s_bar\\.[a-f0-9]+_foo.new.test_", fakeDocker.Created[1]) { t.Errorf("Unexpected containers created %v", fakeDocker.Created) } @@ -475,7 +474,7 @@ func TestSyncPodsCreatesNetAndContainerPullsImage(t *testing.T) { kubelet, fakeDocker := newTestKubelet(t) puller := kubelet.dockerPuller.(*dockertools.FakeDockerPuller) puller.HasImages = []string{} - kubelet.networkContainerImage = "custom_image_name" + kubelet.podInfraContainerImage = "custom_image_name" fakeDocker.ContainerList = []docker.APIContainers{} err := kubelet.SyncPods([]api.BoundPod{ { @@ -507,7 +506,7 @@ func TestSyncPodsCreatesNetAndContainerPullsImage(t *testing.T) { } if len(fakeDocker.Created) != 2 || - !matchString(t, "k8s_net\\.[a-f0-9]+_foo.new.test_", fakeDocker.Created[0]) || + !matchString(t, "k8s_POD\\.[a-f0-9]+_foo.new.test_", fakeDocker.Created[0]) || !matchString(t, "k8s_bar\\.[a-f0-9]+_foo.new.test_", fakeDocker.Created[1]) { t.Errorf("Unexpected containers created %v", fakeDocker.Created) } @@ -518,8 +517,8 @@ func TestSyncPodsWithNetCreatesContainer(t *testing.T) { kubelet, fakeDocker := newTestKubelet(t) fakeDocker.ContainerList = []docker.APIContainers{ { - // network container - Names: []string{"/k8s_net_foo.new.test_12345678_0"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.test_12345678_0"}, ID: "9876", }, } @@ -560,8 +559,8 @@ func TestSyncPodsWithNetCreatesContainerCallsHandler(t *testing.T) { kubelet.httpClient = &fakeHttp fakeDocker.ContainerList = []docker.APIContainers{ { - // network container - Names: []string{"/k8s_net_foo.new.test_12345678_0"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.test_12345678_0"}, ID: "9876", }, } @@ -666,8 +665,8 @@ func TestSyncPodsDeletesWhenSourcesAreReady(t *testing.T) { ID: "1234", }, { - // network container - Names: []string{"/k8s_net_foo.new.test_12345678_42"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.test_12345678_42"}, ID: "9876", }, } @@ -714,8 +713,8 @@ func TestSyncPodsDeletesWhenContainerSourceReady(t *testing.T) { ID: "7492", }, { - // network container - Names: []string{"/k8s_net_boo.default.testSource_12345678_42"}, + // pod infra container + Names: []string{"/k8s_POD_boo.default.testSource_12345678_42"}, ID: "3542", }, @@ -725,8 +724,8 @@ func TestSyncPodsDeletesWhenContainerSourceReady(t *testing.T) { ID: "1234", }, { - // network container - Names: []string{"/k8s_net_foo.new.otherSource_12345678_42"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.otherSource_12345678_42"}, ID: "9876", }, } @@ -767,8 +766,8 @@ func TestSyncPodsDeletes(t *testing.T) { ID: "1234", }, { - // network container - Names: []string{"/k8s_net_foo.new.test_12345678_42"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.test_12345678_42"}, ID: "9876", }, { @@ -805,8 +804,8 @@ func TestSyncPodDeletesDuplicate(t *testing.T) { ID: "1234", }, "9876": &docker.APIContainers{ - // network container - Names: []string{"/k8s_net_bar.new.test_12345678_2222"}, + // pod infra container + Names: []string{"/k8s_POD_bar.new.test_12345678_2222"}, ID: "9876", }, "4567": &docker.APIContainers{ @@ -845,19 +844,8 @@ func TestSyncPodDeletesDuplicate(t *testing.T) { } } -type FalseHealthChecker struct{} - -func (f *FalseHealthChecker) HealthCheck(podFullName string, podUID types.UID, status api.PodStatus, container api.Container) (health.Status, error) { - return health.Unhealthy, nil -} - -func (f *FalseHealthChecker) CanCheck(probe *api.LivenessProbe) bool { - return true -} - func TestSyncPodBadHash(t *testing.T) { kubelet, fakeDocker := newTestKubelet(t) - kubelet.healthChecker = &FalseHealthChecker{} dockerContainers := dockertools.DockerContainers{ "1234": &docker.APIContainers{ // the k8s prefix is required for the kubelet to manage the container @@ -865,8 +853,8 @@ func TestSyncPodBadHash(t *testing.T) { ID: "1234", }, "9876": &docker.APIContainers{ - // network container - Names: []string{"/k8s_net_foo.new.test_12345678_42"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.test_12345678_42"}, ID: "9876", }, } @@ -904,7 +892,6 @@ func TestSyncPodBadHash(t *testing.T) { func TestSyncPodUnhealthy(t *testing.T) { kubelet, fakeDocker := newTestKubelet(t) - kubelet.healthChecker = &FalseHealthChecker{} dockerContainers := dockertools.DockerContainers{ "1234": &docker.APIContainers{ // the k8s prefix is required for the kubelet to manage the container @@ -912,8 +899,8 @@ func TestSyncPodUnhealthy(t *testing.T) { ID: "1234", }, "9876": &docker.APIContainers{ - // network container - Names: []string{"/k8s_net_foo.new.test_12345678_42"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.test_12345678_42"}, ID: "9876", }, } @@ -927,7 +914,7 @@ func TestSyncPodUnhealthy(t *testing.T) { Spec: api.PodSpec{ Containers: []api.Container{ {Name: "bar", - LivenessProbe: &api.LivenessProbe{ + LivenessProbe: &api.Probe{ // Always returns healthy == false }, }, @@ -1559,8 +1546,8 @@ func TestSyncPodEventHandlerFails(t *testing.T) { } dockerContainers := dockertools.DockerContainers{ "9876": &docker.APIContainers{ - // network container - Names: []string{"/k8s_net_foo.new.test_12345678_42"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.test_12345678_42"}, ID: "9876", }, } @@ -1607,33 +1594,33 @@ func TestKubeletGarbageCollection(t *testing.T) { { containers: []docker.APIContainers{ { - // network container - Names: []string{"/k8s_net_foo.new.test_.deadbeef_42"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"}, ID: "1876", }, { - // network container - Names: []string{"/k8s_net_foo.new.test_.deadbeef_42"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"}, ID: "2876", }, { - // network container - Names: []string{"/k8s_net_foo.new.test_.deadbeef_42"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"}, ID: "3876", }, { - // network container - Names: []string{"/k8s_net_foo.new.test_.deadbeef_42"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"}, ID: "4876", }, { - // network container - Names: []string{"/k8s_net_foo.new.test_.deadbeef_42"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"}, ID: "5876", }, { - // network container - Names: []string{"/k8s_net_foo.new.test_.deadbeef_42"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"}, ID: "6876", }, }, @@ -1651,38 +1638,38 @@ func TestKubeletGarbageCollection(t *testing.T) { { containers: []docker.APIContainers{ { - // network container - Names: []string{"/k8s_net_foo.new.test_.deadbeef_42"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"}, ID: "1876", }, { - // network container - Names: []string{"/k8s_net_foo.new.test_.deadbeef_42"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"}, ID: "2876", }, { - // network container - Names: []string{"/k8s_net_foo.new.test_.deadbeef_42"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"}, ID: "3876", }, { - // network container - Names: []string{"/k8s_net_foo.new.test_.deadbeef_42"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"}, ID: "4876", }, { - // network container - Names: []string{"/k8s_net_foo.new.test_.deadbeef_42"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"}, ID: "5876", }, { - // network container - Names: []string{"/k8s_net_foo.new.test_.deadbeef_42"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"}, ID: "6876", }, { - // network container - Names: []string{"/k8s_net_foo.new.test_.deadbeef_42"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"}, ID: "7876", }, }, @@ -1707,8 +1694,8 @@ func TestKubeletGarbageCollection(t *testing.T) { { containers: []docker.APIContainers{ { - // network container - Names: []string{"/k8s_net_foo.new.test_.deadbeef_42"}, + // pod infra container + Names: []string{"/k8s_POD_foo.new.test_.deadbeef_42"}, ID: "1876", }, }, @@ -1896,7 +1883,7 @@ func TestSyncPodsWithPullPolicy(t *testing.T) { kubelet, fakeDocker := newTestKubelet(t) puller := kubelet.dockerPuller.(*dockertools.FakeDockerPuller) puller.HasImages = []string{"existing_one", "want:latest"} - kubelet.networkContainerImage = "custom_image_name" + kubelet.podInfraContainerImage = "custom_image_name" fakeDocker.ContainerList = []docker.APIContainers{} err := kubelet.SyncPods([]api.BoundPod{ { diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/leaky/leaky.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/leaky/leaky.go new file mode 100644 index 000000000000..518565760ca6 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/leaky/leaky.go @@ -0,0 +1,25 @@ +/* +Copyright 2015 Google Inc. All rights reserved. + +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 leaky holds bits of kubelet that should be internal but have leaked +// out through bad abstractions. TODO: delete all of this. +package leaky + +const ( + // This is used in a few places outside of Kubelet, such as indexing + // into the container info. + PodInfraContainerName = "POD" +) diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/probe.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/probe.go new file mode 100644 index 000000000000..8d107872d707 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/probe.go @@ -0,0 +1,125 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 kubelet + +import ( + "fmt" + "strconv" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/probe" + execprobe "github.com/GoogleCloudPlatform/kubernetes/pkg/probe/exec" + httprobe "github.com/GoogleCloudPlatform/kubernetes/pkg/probe/http" + tcprobe "github.com/GoogleCloudPlatform/kubernetes/pkg/probe/tcp" + "github.com/GoogleCloudPlatform/kubernetes/pkg/types" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util/exec" + + "github.com/golang/glog" +) + +var ( + execprober = execprobe.New() + httprober = httprobe.New() + tcprober = tcprobe.New() +) + +func (kl *Kubelet) probeContainer(p *api.Probe, podFullName string, podUID types.UID, status api.PodStatus, container api.Container) (probe.Status, error) { + if p.Exec != nil { + return execprober.Probe(kl.newExecInContainer(podFullName, podUID, container)) + } + if p.HTTPGet != nil { + port, err := extractPort(p.HTTPGet.Port, container) + if err != nil { + return probe.Unknown, err + } + return httprober.Probe(extractGetParams(p.HTTPGet, status, port)) + } + if p.TCPSocket != nil { + port, err := extractPort(p.TCPSocket.Port, container) + if err != nil { + return probe.Unknown, err + } + return tcprober.Probe(status.PodIP, port) + } + glog.Warningf("Failed to find probe builder for %s %+v", container.Name, container.LivenessProbe) + return probe.Unknown, nil +} + +func extractGetParams(action *api.HTTPGetAction, status api.PodStatus, port int) (string, int, string) { + host := action.Host + if host == "" { + host = status.PodIP + } + return host, port, action.Path +} + +func extractPort(param util.IntOrString, container api.Container) (int, error) { + port := -1 + var err error + switch param.Kind { + case util.IntstrInt: + port := param.IntVal + if port > 0 && port < 65536 { + return port, nil + } + return port, fmt.Errorf("invalid port number: %v", port) + case util.IntstrString: + port = findPortByName(container, param.StrVal) + if port == -1 { + // Last ditch effort - maybe it was an int stored as string? + if port, err = strconv.Atoi(param.StrVal); err != nil { + return port, err + } + } + if port > 0 && port < 65536 { + return port, nil + } + return port, fmt.Errorf("invalid port number: %v", port) + default: + return port, fmt.Errorf("IntOrString had no kind: %+v", param) + } +} + +// findPortByName is a helper function to look up a port in a container by name. +// Returns the HostPort if found, -1 if not found. +func findPortByName(container api.Container, portName string) int { + for _, port := range container.Ports { + if port.Name == portName { + return port.HostPort + } + } + return -1 +} + +type execInContainer struct { + run func() ([]byte, error) +} + +func (kl *Kubelet) newExecInContainer(podFullName string, podUID types.UID, container api.Container) exec.Cmd { + return execInContainer{func() ([]byte, error) { + return kl.RunInContainer(podFullName, podUID, container.Name, container.LivenessProbe.Exec.Command) + }} +} + +func (eic execInContainer) CombinedOutput() ([]byte, error) { + return eic.run() +} + +func (eic execInContainer) SetDir(dir string) { + //unimplemented +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/http_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/probe_test.go similarity index 57% rename from Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/http_test.go rename to Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/probe_test.go index f83649cb9c5d..e7207777daf0 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/http_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/probe_test.go @@ -1,5 +1,5 @@ /* -Copyright 2014 Google Inc. All rights reserved. +Copyright 2015 Google Inc. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,19 +14,35 @@ See the License for the specific language governing permissions and limitations under the License. */ -package health +package kubelet import ( - "net" - "net/http" - "net/http/httptest" - "net/url" "testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" ) +func TestFindPortByName(t *testing.T) { + container := api.Container{ + Ports: []api.Port{ + { + Name: "foo", + HostPort: 8080, + }, + { + Name: "bar", + HostPort: 9000, + }, + }, + } + want := 8080 + got := findPortByName(container, "foo") + if got != want { + t.Errorf("Expected %v, got %v", want, got) + } +} + func TestGetURLParts(t *testing.T) { testCases := []struct { probe *api.HTTPGetAction @@ -49,17 +65,20 @@ func TestGetURLParts(t *testing.T) { state := api.PodStatus{PodIP: "127.0.0.1"} container := api.Container{ Ports: []api.Port{{Name: "found", HostPort: 93}}, - LivenessProbe: &api.LivenessProbe{ - HTTPGet: test.probe, + LivenessProbe: &api.Probe{ + Handler: api.Handler{ + HTTPGet: test.probe, + }, }, } - host, port, path, err := getURLParts(state, container) - if !test.ok && err == nil { - t.Errorf("Expected error for %+v, got %s:%d/%s", test, host, port, path) - } + p, err := extractPort(test.probe.Port, container) if test.ok && err != nil { t.Errorf("Unexpected error: %v", err) } + host, port, path := extractGetParams(test.probe, state, p) + if !test.ok && err == nil { + t.Errorf("Expected error for %+v, got %s:%d/%s", test, host, port, path) + } if test.ok { if host != test.host || port != test.port || path != test.path { t.Errorf("Expected %s:%d/%s, got %s:%d/%s", @@ -69,69 +88,43 @@ func TestGetURLParts(t *testing.T) { } } -func TestFormatURL(t *testing.T) { +func TestGetTCPAddrParts(t *testing.T) { testCases := []struct { - host string - port int - path string - result string + probe *api.TCPSocketAction + ok bool + host string + port int }{ - {"localhost", 93, "", "http://localhost:93"}, - {"localhost", 93, "/path", "http://localhost:93/path"}, + {&api.TCPSocketAction{Port: util.NewIntOrStringFromInt(-1)}, false, "", -1}, + {&api.TCPSocketAction{Port: util.NewIntOrStringFromString("")}, false, "", -1}, + {&api.TCPSocketAction{Port: util.NewIntOrStringFromString("-1")}, false, "", -1}, + {&api.TCPSocketAction{Port: util.NewIntOrStringFromString("not-found")}, false, "", -1}, + {&api.TCPSocketAction{Port: util.NewIntOrStringFromString("found")}, true, "1.2.3.4", 93}, + {&api.TCPSocketAction{Port: util.NewIntOrStringFromInt(76)}, true, "1.2.3.4", 76}, + {&api.TCPSocketAction{Port: util.NewIntOrStringFromString("118")}, true, "1.2.3.4", 118}, } - for _, test := range testCases { - url := formatURL(test.host, test.port, test.path) - if url != test.result { - t.Errorf("Expected %s, got %s", test.result, url) - } - } -} -func TestHTTPHealthChecker(t *testing.T) { - testCases := []struct { - probe *api.HTTPGetAction - status int - health Status - }{ - // The probe will be filled in below. This is primarily testing that an HTTP GET happens. - {&api.HTTPGetAction{}, http.StatusOK, Healthy}, - {&api.HTTPGetAction{}, -1, Unhealthy}, - {nil, -1, Unknown}, - } - hc := &HTTPHealthChecker{ - client: &http.Client{}, - } for _, test := range testCases { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(test.status) - })) - u, err := url.Parse(ts.URL) - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - host, port, err := net.SplitHostPort(u.Host) - if err != nil { - t.Errorf("Unexpected error: %v", err) - } + host := "1.2.3.4" container := api.Container{ - LivenessProbe: &api.LivenessProbe{ - HTTPGet: test.probe, + Ports: []api.Port{{Name: "found", HostPort: 93}}, + LivenessProbe: &api.Probe{ + Handler: api.Handler{ + TCPSocket: test.probe, + }, }, } - params := container.LivenessProbe.HTTPGet - if params != nil { - params.Port = util.NewIntOrStringFromString(port) - params.Host = host - } - health, err := hc.HealthCheck("test", "", api.PodStatus{PodIP: host}, container) - if test.health == Unknown && err == nil { - t.Errorf("Expected error") + port, err := extractPort(test.probe.Port, container) + if !test.ok && err == nil { + t.Errorf("Expected error for %+v, got %s:%d", test, host, port) } - if test.health != Unknown && err != nil { + if test.ok && err != nil { t.Errorf("Unexpected error: %v", err) } - if health != test.health { - t.Errorf("Expected %v, got %v", test.health, health) + if test.ok { + if host != test.host || port != test.port { + t.Errorf("Expected %s:%d, got %s:%d", test.host, test.port, host, port) + } } } } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/util.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/util.go index 079acc046586..07bb42bbb8a9 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/util.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/util.go @@ -17,14 +17,12 @@ limitations under the License. package kubelet import ( - "net/http" "strconv" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/capabilities" "github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client/record" - "github.com/GoogleCloudPlatform/kubernetes/pkg/health" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/coreos/go-etcd/etcd" @@ -46,15 +44,6 @@ func MonitorCAdvisor(k *Kubelet, cp uint) { k.SetCadvisorClient(cadvisorClient) } -// TODO: move this into the kubelet itself -func InitHealthChecking(k *Kubelet) { - // TODO: These should probably become more plugin-ish: register a factory func - // in each checker's init(), iterate those here. - health.AddHealthChecker(health.NewExecHealthChecker(k)) - health.AddHealthChecker(health.NewHTTPHealthChecker(&http.Client{})) - health.AddHealthChecker(&health.TCPHealthChecker{}) -} - // TODO: move this into a pkg/tools/etcd_tools func EtcdClientOrDie(etcdServerList util.StringList, etcdConfigFile string) tools.EtcdClient { if len(etcdServerList) > 0 { diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/volume/gce_pd/gce_pd.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/volume/gce_pd/gce_pd.go index d93b9ff72918..cdec6a3f0e40 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/volume/gce_pd/gce_pd.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/volume/gce_pd/gce_pd.go @@ -151,6 +151,13 @@ type gcePersistentDisk struct { legacyMode bool } +func detachDiskLogError(pd *gcePersistentDisk) { + err := pd.manager.DetachDisk(pd, "/dev/disk/by-id/google-"+pd.pdName) + if err != nil { + glog.Warningf("Failed to detach disk: %v (%v)", pd, err) + } +} + // SetUp attaches the disk and bind mounts to the volume path. func (pd *gcePersistentDisk) SetUp() error { if pd.legacyMode { @@ -178,6 +185,8 @@ func (pd *gcePersistentDisk) SetUp() error { volPath := pd.GetPath() if err := os.MkdirAll(volPath, 0750); err != nil { + // TODO: we should really eject the attach/detach out into its own control loop. + detachDiskLogError(pd) return err } @@ -186,6 +195,8 @@ func (pd *gcePersistentDisk) SetUp() error { err = pd.mounter.Mount(globalPDPath, pd.GetPath(), "", mount.FlagBind|flags, "") if err != nil { os.RemoveAll(pd.GetPath()) + // TODO: we should really eject the attach/detach out into its own control loop. + detachDiskLogError(pd) return err } @@ -223,9 +234,6 @@ func (pd *gcePersistentDisk) TearDown() error { return err } refCount-- - if err := os.RemoveAll(pd.GetPath()); err != nil { - return err - } // If refCount is 1, then all bind mounts have been removed, and the // remaining reference is the global mount. It is safe to detach. if refCount == 1 { @@ -233,5 +241,8 @@ func (pd *gcePersistentDisk) TearDown() error { return err } } + if err := os.RemoveAll(pd.GetPath()); err != nil { + return err + } return nil } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/volume/gce_pd/mount_util_linux.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/volume/gce_pd/mount_util_unix.go similarity index 100% rename from Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/volume/gce_pd/mount_util_linux.go rename to Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/volume/gce_pd/mount_util_unix.go diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/volume/gce_pd/mount_util_unsupported.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/volume/gce_pd/mount_util_unsupported.go index 1d6e7edb18ec..03b4bc6e2ddd 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/volume/gce_pd/mount_util_unsupported.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/volume/gce_pd/mount_util_unsupported.go @@ -1,4 +1,4 @@ -// +build !linux +// +build windows /* Copyright 2014 Google Inc. All rights reserved. diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/master.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/master.go index ae3aa2b599a6..cc81000fa52e 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/master.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/master.go @@ -47,12 +47,15 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/etcd" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/event" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" + "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/limitrange" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod" + "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota" + "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequotausage" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" - //"github.com/GoogleCloudPlatform/kubernetes/pkg/ui" + "github.com/GoogleCloudPlatform/kubernetes/pkg/ui" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/emicklei/go-restful" @@ -65,7 +68,6 @@ type Config struct { Client *client.Client Cloud cloudprovider.Interface EtcdHelper tools.EtcdHelper - HealthCheckMinions bool EventTTL time.Duration MinionRegexp string KubeletClient client.KubeletClient @@ -102,16 +104,18 @@ type Config struct { // Master contains state for a Kubernetes cluster master/api server. type Master struct { // "Inputs", Copied from Config - podRegistry pod.Registry - controllerRegistry controller.Registry - serviceRegistry service.Registry - endpointRegistry endpoint.Registry - minionRegistry minion.Registry - bindingRegistry binding.Registry - eventRegistry generic.Registry - storage map[string]apiserver.RESTStorage - client *client.Client - portalNet *net.IPNet + podRegistry pod.Registry + controllerRegistry controller.Registry + serviceRegistry service.Registry + endpointRegistry endpoint.Registry + minionRegistry minion.Registry + bindingRegistry binding.Registry + eventRegistry generic.Registry + limitRangeRegistry generic.Registry + resourceQuotaRegistry resourcequota.Registry + storage map[string]apiserver.RESTStorage + client *client.Client + portalNet *net.IPNet mux apiserver.Mux muxHelper *apiserver.MuxHelper @@ -230,7 +234,7 @@ func setDefaults(c *Config) { // any unhandled paths to "Handler". func New(c *Config) *Master { setDefaults(c) - minionRegistry := makeMinionRegistry(c) + minionRegistry := etcd.NewRegistry(c.EtcdHelper, nil) serviceRegistry := etcd.NewRegistry(c.EtcdHelper, nil) boundPodFactory := &pod.BasicBoundPodFactory{ ServiceRegistry: serviceRegistry, @@ -248,6 +252,8 @@ func New(c *Config) *Master { bindingRegistry: etcd.NewRegistry(c.EtcdHelper, boundPodFactory), eventRegistry: event.NewEtcdRegistry(c.EtcdHelper, uint64(c.EventTTL.Seconds())), minionRegistry: minionRegistry, + limitRangeRegistry: limitrange.NewEtcdRegistry(c.EtcdHelper), + resourceQuotaRegistry: resourcequota.NewEtcdRegistry(c.EtcdHelper), client: c.Client, portalNet: c.PortalNet, rootWebService: new(restful.WebService), @@ -323,15 +329,6 @@ func logStackOnRecover(panicReason interface{}, httpWriter http.ResponseWriter) glog.Errorln(buffer.String()) } -func makeMinionRegistry(c *Config) minion.Registry { - var minionRegistry minion.Registry = etcd.NewRegistry(c.EtcdHelper, nil) - // TODO: plumb in nodeIPCache here - if c.HealthCheckMinions { - minionRegistry = minion.NewHealthyRegistry(minionRegistry, c.KubeletClient, util.RealClock{}, 20*time.Second) - } - return minionRegistry -} - // init initializes master. func (m *Master) init(c *Config) { var userContexts = handlers.NewUserRequestContext() @@ -344,7 +341,8 @@ func (m *Master) init(c *Config) { RESTStorageToNodes(nodeRESTStorage).Nodes(), m.podRegistry, ) - go util.Forever(func() { podCache.UpdateAllContainers() }, time.Second*30) + go util.Forever(func() { podCache.UpdateAllContainers() }, time.Second*5) + go util.Forever(func() { podCache.GarbageCollectPodStatus() }, time.Minute*30) // TODO: Factor out the core API registration m.storage = map[string]apiserver.RESTStorage{ @@ -361,6 +359,10 @@ func (m *Master) init(c *Config) { // TODO: should appear only in scheduler API group. "bindings": binding.NewREST(m.bindingRegistry), + + "limitRanges": limitrange.NewREST(m.limitRangeRegistry), + "resourceQuotas": resourcequota.NewREST(m.resourceQuotaRegistry), + "resourceQuotaUsages": resourcequotausage.NewREST(m.resourceQuotaRegistry), } apiVersions := []string{"v1beta1", "v1beta2"} @@ -382,16 +384,16 @@ func (m *Master) init(c *Config) { // Register root handler. // We do not register this using restful Webservice since we do not want to surface this in api docs. - //m.mux.HandleFunc("/", apiserver.IndexHandler(m.handlerContainer, m.muxHelper)) + m.mux.HandleFunc("/", apiserver.IndexHandler(m.handlerContainer, m.muxHelper)) // TODO: use go-restful apiserver.InstallValidator(m.muxHelper, func() map[string]apiserver.Server { return m.getServersToValidate(c) }) if c.EnableLogsSupport { apiserver.InstallLogsSupport(m.muxHelper) } - /*if c.EnableUISupport { - ui.InstallSupport(m.mux) - }*/ + if c.EnableUISupport { + ui.InstallSupport(m.muxHelper, m.enableSwaggerSupport) + } // TODO: install runtime/pprof handler // See github.com/emicklei/go-restful/blob/master/examples/restful-cpuprofiler-service.go diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/pod_cache.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/pod_cache.go index 7b2ba52a0ba1..53ef5ab82e81 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/pod_cache.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/pod_cache.go @@ -20,8 +20,8 @@ import ( "sync" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/client" + "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/leaky" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod" @@ -47,7 +47,7 @@ type PodCache struct { podStatus map[objKey]api.PodStatus // nodes that we know exist. Cleared at the beginning of each // UpdateAllPods call. - currentNodes map[objKey]bool + currentNodes map[objKey]api.NodeStatus } type objKey struct { @@ -63,54 +63,82 @@ func NewPodCache(ipCache IPGetter, info client.PodInfoGetter, nodes client.NodeI containerInfo: info, pods: pods, nodes: nodes, - currentNodes: map[objKey]bool{}, + currentNodes: map[objKey]api.NodeStatus{}, podStatus: map[objKey]api.PodStatus{}, } } // GetPodStatus gets the stored pod status. func (p *PodCache) GetPodStatus(namespace, name string) (*api.PodStatus, error) { + status := p.getPodStatusInternal(namespace, name) + if status != nil { + return status, nil + } + return p.updateCacheAndReturn(namespace, name) +} + +func (p *PodCache) updateCacheAndReturn(namespace, name string) (*api.PodStatus, error) { + pod, err := p.pods.GetPod(api.WithNamespace(api.NewContext(), namespace), name) + if err != nil { + return nil, err + } + if err := p.updatePodStatus(pod); err != nil { + return nil, err + } + status := p.getPodStatusInternal(namespace, name) + if status == nil { + glog.Warningf("nil status after successful update. that's odd... (%s %s)", namespace, name) + return nil, client.ErrPodInfoNotAvailable + } + return status, nil +} + +func (p *PodCache) getPodStatusInternal(namespace, name string) *api.PodStatus { p.lock.Lock() defer p.lock.Unlock() value, ok := p.podStatus[objKey{namespace, name}] if !ok { - return nil, client.ErrPodInfoNotAvailable + return nil } // Make a copy - return &value, nil + return &value +} + +func (p *PodCache) ClearPodStatus(namespace, name string) { + p.lock.Lock() + defer p.lock.Unlock() + + delete(p.podStatus, objKey{namespace, name}) } -func (p *PodCache) nodeExistsInCache(name string) (exists, cacheHit bool) { +func (p *PodCache) getNodeStatusInCache(name string) (*api.NodeStatus, bool) { p.lock.Lock() defer p.lock.Unlock() - exists, cacheHit = p.currentNodes[objKey{"", name}] - return exists, cacheHit + nodeStatus, cacheHit := p.currentNodes[objKey{"", name}] + return &nodeStatus, cacheHit } // lock must *not* be held -func (p *PodCache) nodeExists(name string) bool { - exists, cacheHit := p.nodeExistsInCache(name) +func (p *PodCache) getNodeStatus(name string) (*api.NodeStatus, error) { + nodeStatus, cacheHit := p.getNodeStatusInCache(name) if cacheHit { - return exists + return nodeStatus, nil } // TODO: suppose there's N concurrent requests for node "foo"; in that case // it might be useful to block all of them and only look up "foo" once. // (This code will make up to N lookups.) One way of doing that would be to // have a pool of M mutexes and require that before looking up "foo" you must // lock mutex hash("foo") % M. - _, err := p.nodes.Get(name) - exists = true + node, err := p.nodes.Get(name) if err != nil { - exists = false - if !errors.IsNotFound(err) { - glog.Errorf("Unexpected error type verifying minion existence: %+v", err) - } + glog.Errorf("Unexpected error verifying node existence: %+v", err) + return nil, err } p.lock.Lock() defer p.lock.Unlock() - p.currentNodes[objKey{"", name}] = exists - return exists + p.currentNodes[objKey{"", name}] = node.Status + return &node.Status, nil } // TODO: once Host gets moved to spec, this can take a podSpec + metadata instead of an @@ -138,12 +166,26 @@ func (p *PodCache) computePodStatus(pod *api.Pod) (api.PodStatus, error) { return newStatus, nil } - if !p.nodeExists(pod.Status.Host) { - // Assigned to non-existing node. - newStatus.Phase = api.PodFailed + nodeStatus, err := p.getNodeStatus(pod.Status.Host) + + // Assigned to non-existing node. + if err != nil || len(nodeStatus.Conditions) == 0 { + newStatus.Phase = api.PodUnknown return newStatus, nil } + // Assigned to an unhealthy node. + for _, condition := range nodeStatus.Conditions { + if condition.Kind == api.NodeReady && condition.Status == api.ConditionNone { + newStatus.Phase = api.PodUnknown + return newStatus, nil + } + if condition.Kind == api.NodeReachable && condition.Status == api.ConditionNone { + newStatus.Phase = api.PodUnknown + return newStatus, nil + } + } + result, err := p.containerInfo.GetPodStatus(pod.Status.Host, pod.Namespace, pod.Name) newStatus.HostIP = p.ipCache.GetInstanceIP(pod.Status.Host) @@ -152,7 +194,7 @@ func (p *PodCache) computePodStatus(pod *api.Pod) (api.PodStatus, error) { } else { newStatus.Info = result.Status.Info newStatus.Phase = getPhase(&pod.Spec, newStatus.Info) - if netContainerInfo, ok := newStatus.Info["net"]; ok { + if netContainerInfo, ok := newStatus.Info[leaky.PodInfraContainerName]; ok { if netContainerInfo.PodIP != "" { newStatus.PodIP = netContainerInfo.PodIP } @@ -161,10 +203,23 @@ func (p *PodCache) computePodStatus(pod *api.Pod) (api.PodStatus, error) { return newStatus, err } -func (p *PodCache) resetNodeExistenceCache() { +func (p *PodCache) GarbageCollectPodStatus() { + pods, err := p.pods.ListPods(api.NewContext(), labels.Everything()) + if err != nil { + glog.Errorf("Error getting pod list: %v", err) + } + keys := map[objKey]bool{} + for _, pod := range pods.Items { + keys[objKey{pod.Namespace, pod.Name}] = true + } p.lock.Lock() defer p.lock.Unlock() - p.currentNodes = map[objKey]bool{} + for key := range p.podStatus { + if _, found := keys[key]; !found { + glog.Infof("Deleting orphaned cache entry: %v", key) + delete(p.podStatus, key) + } + } } // UpdateAllContainers updates information about all containers. @@ -172,8 +227,6 @@ func (p *PodCache) resetNodeExistenceCache() { // calling again, or risk having new info getting clobbered by delayed // old info. func (p *PodCache) UpdateAllContainers() { - p.resetNodeExistenceCache() - ctx := api.NewContext() pods, err := p.pods.ListPods(ctx, labels.Everything()) if err != nil { diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/pod_cache_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/pod_cache_test.go index 37f7257ad9f2..a88599ca71c0 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/pod_cache_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/pod_cache_test.go @@ -24,6 +24,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/client" + "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/leaky" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" ) @@ -125,15 +126,72 @@ func TestPodCacheGet(t *testing.T) { } } +func TestPodCacheDelete(t *testing.T) { + config := podCacheTestConfig{ + err: client.ErrPodInfoNotAvailable, + } + cache := config.Construct() + + expected := api.PodStatus{ + Info: api.PodInfo{ + "foo": api.ContainerStatus{}, + }, + } + cache.podStatus[objKey{api.NamespaceDefault, "foo"}] = expected + + info, err := cache.GetPodStatus(api.NamespaceDefault, "foo") + if err != nil { + t.Errorf("Unexpected error: %+v", err) + } + if !reflect.DeepEqual(info, &expected) { + t.Errorf("Unexpected mismatch. Expected: %+v, Got: %+v", &expected, info) + } + + cache.ClearPodStatus(api.NamespaceDefault, "foo") + + _, err = cache.GetPodStatus(api.NamespaceDefault, "foo") + if err == nil { + t.Errorf("Unexpected non-error after deleting") + } + if err != client.ErrPodInfoNotAvailable { + t.Errorf("Unexpected error: %v, expecting: %v", err, client.ErrPodInfoNotAvailable) + } + +} + func TestPodCacheGetMissing(t *testing.T) { - cache := NewPodCache(nil, nil, nil, nil) + pod1 := makePod(api.NamespaceDefault, "foo", "machine", "bar") + config := podCacheTestConfig{ + ipFunc: func(host string) string { + if host == "machine" { + return "1.2.3.5" + } + return "" + }, + kubeletContainerInfo: api.PodStatus{ + Info: api.PodInfo{"bar": api.ContainerStatus{}}}, + nodes: []api.Node{*makeHealthyNode("machine")}, + pod: pod1, + } + cache := config.Construct() status, err := cache.GetPodStatus(api.NamespaceDefault, "foo") - if err == nil { - t.Errorf("Unexpected non-error: %+v", err) + if err != nil { + t.Errorf("Unexpected error: %+v", err) } - if status != nil { - t.Errorf("Unexpected status: %+v", status) + if status == nil { + t.Errorf("Unexpected non-status.") + } + expected := &api.PodStatus{ + Phase: "Pending", + Host: "machine", + HostIP: "1.2.3.5", + Info: api.PodInfo{ + "bar": api.ContainerStatus{}, + }, + } + if !reflect.DeepEqual(status, expected) { + t.Errorf("expected:\n%#v\ngot:\n%#v\n", expected, status) } } @@ -147,6 +205,8 @@ type podCacheTestConfig struct { ipFunc func(string) string // Construct will set a default if nil nodes []api.Node pods []api.Pod + pod *api.Pod + err error kubeletContainerInfo api.PodStatus // Construct will fill in these fields @@ -172,6 +232,8 @@ func (c *podCacheTestConfig) Construct() *PodCache { }, } c.fakePods = registrytest.NewPodRegistry(&api.PodList{Items: c.pods}) + c.fakePods.Pod = c.pod + c.fakePods.Err = c.err return NewPodCache( fakeIPCache(c.ipFunc), c.fakePodInfo, @@ -186,21 +248,31 @@ func makePod(namespace, name, host string, containers ...string) *api.Pod { Status: api.PodStatus{Host: host}, } for _, c := range containers { - pod.Spec.Containers = append(pod.Spec.Containers, api.Container{ - Name: c, - }) + pod.Spec.Containers = append(pod.Spec.Containers, api.Container{Name: c}) } return pod } -func makeNode(name string) *api.Node { +func makeHealthyNode(name string) *api.Node { + return &api.Node{ + ObjectMeta: api.ObjectMeta{Name: name}, + Status: api.NodeStatus{Conditions: []api.NodeCondition{ + {Kind: api.NodeReady, Status: api.ConditionFull}, + }}, + } +} + +func makeUnhealthyNode(name string) *api.Node { return &api.Node{ ObjectMeta: api.ObjectMeta{Name: name}, + Status: api.NodeStatus{Conditions: []api.NodeCondition{ + {Kind: api.NodeReady, Status: api.ConditionNone}, + }}, } } func TestPodUpdateAllContainers(t *testing.T) { - pod := makePod(api.NamespaceDefault, "foo", "machine", "bar") + pod1 := makePod(api.NamespaceDefault, "foo", "machine", "bar") pod2 := makePod(api.NamespaceDefault, "baz", "machine", "qux") config := podCacheTestConfig{ ipFunc: func(host string) string { @@ -211,8 +283,8 @@ func TestPodUpdateAllContainers(t *testing.T) { }, kubeletContainerInfo: api.PodStatus{ Info: api.PodInfo{"bar": api.ContainerStatus{}}}, - nodes: []api.Node{*makeNode("machine")}, - pods: []api.Pod{*pod, *pod2}, + nodes: []api.Node{*makeHealthyNode("machine")}, + pods: []api.Pod{*pod1, *pod2}, } cache := config.Construct() @@ -254,7 +326,7 @@ func TestFillPodStatusNoHost(t *testing.T) { pod := makePod(api.NamespaceDefault, "foo", "", "bar") config := podCacheTestConfig{ kubeletContainerInfo: api.PodStatus{}, - nodes: []api.Node{*makeNode("machine")}, + nodes: []api.Node{*makeHealthyNode("machine")}, pods: []api.Pod{*pod}, } cache := config.Construct() @@ -283,7 +355,7 @@ func TestFillPodStatusMissingMachine(t *testing.T) { } status, err := cache.GetPodStatus(pod.Namespace, pod.Name) - if e, a := api.PodFailed, status.Phase; e != a { + if e, a := api.PodUnknown, status.Phase; e != a { t.Errorf("Expected: %+v, Got %+v", e, a) } } @@ -299,7 +371,7 @@ func TestFillPodStatus(t *testing.T) { HostIP: "ip of machine", PodIP: expectedIP, Info: api.PodInfo{ - "net": { + leaky.PodInfraContainerName: { State: api.ContainerState{ Running: &api.ContainerStateRunning{ StartedAt: util.NewTime(expectedTime), @@ -310,7 +382,7 @@ func TestFillPodStatus(t *testing.T) { }, }, }, - nodes: []api.Node{*makeNode("machine")}, + nodes: []api.Node{*makeHealthyNode("machine")}, pods: []api.Pod{*pod}, } cache := config.Construct() @@ -334,10 +406,10 @@ func TestFillPodInfoNoData(t *testing.T) { Host: "machine", HostIP: "ip of machine", Info: api.PodInfo{ - "net": {}, + leaky.PodInfraContainerName: {}, }, }, - nodes: []api.Node{*makeNode("machine")}, + nodes: []api.Node{*makeHealthyNode("machine")}, pods: []api.Pod{*pod}, } cache := config.Construct() @@ -376,6 +448,7 @@ func TestPodPhaseWithBadNode(t *testing.T) { tests := []struct { pod *api.Pod + nodes []api.Node status api.PodPhase test string }{ @@ -383,10 +456,11 @@ func TestPodPhaseWithBadNode(t *testing.T) { &api.Pod{ Spec: desiredState, Status: api.PodStatus{ - Host: "machine-2", + Host: "machine-two", }, }, - api.PodFailed, + []api.Node{}, + api.PodUnknown, "no info, but bad machine", }, { @@ -400,7 +474,8 @@ func TestPodPhaseWithBadNode(t *testing.T) { Host: "machine-two", }, }, - api.PodFailed, + []api.Node{}, + api.PodUnknown, "all running but minion is missing", }, { @@ -414,14 +489,45 @@ func TestPodPhaseWithBadNode(t *testing.T) { Host: "machine-two", }, }, - api.PodFailed, + []api.Node{}, + api.PodUnknown, "all stopped but minion missing", }, + { + &api.Pod{ + Spec: desiredState, + Status: api.PodStatus{ + Info: map[string]api.ContainerStatus{ + "containerA": runningState, + "containerB": runningState, + }, + Host: "machine-two", + }, + }, + []api.Node{*makeUnhealthyNode("machine-two")}, + api.PodUnknown, + "all running but minion is unhealthy", + }, + { + &api.Pod{ + Spec: desiredState, + Status: api.PodStatus{ + Info: map[string]api.ContainerStatus{ + "containerA": stoppedState, + "containerB": stoppedState, + }, + Host: "machine-two", + }, + }, + []api.Node{*makeUnhealthyNode("machine-two")}, + api.PodUnknown, + "all stopped but minion is unhealthy", + }, } for _, test := range tests { config := podCacheTestConfig{ kubeletContainerInfo: test.pod.Status, - nodes: []api.Node{}, + nodes: test.nodes, pods: []api.Pod{*test.pod}, } cache := config.Construct() @@ -755,3 +861,26 @@ func TestPodPhaseWithRestartOnFailure(t *testing.T) { } } } + +func TestGarbageCollection(t *testing.T) { + pod1 := makePod(api.NamespaceDefault, "foo", "machine", "bar") + pod2 := makePod(api.NamespaceDefault, "baz", "machine", "qux") + config := podCacheTestConfig{ + pods: []api.Pod{*pod1, *pod2}, + } + cache := config.Construct() + + expected := api.PodStatus{ + Info: api.PodInfo{ + "extra": api.ContainerStatus{}, + }, + } + cache.podStatus[objKey{api.NamespaceDefault, "extra"}] = expected + + cache.GarbageCollectPodStatus() + + status, found := cache.podStatus[objKey{api.NamespaceDefault, "extra"}] + if found { + t.Errorf("unexpectedly found: %v for key %v", status, objKey{api.NamespaceDefault, "extra"}) + } +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/publish.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/publish.go index 41b91b6af2a4..1f9477e03849 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/publish.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/publish.go @@ -104,7 +104,7 @@ func (m *Master) createMasterServiceIfNeeded(serviceName string, port int) error // If all worked, we get back an *api.Service object. return nil } - return fmt.Errorf("unexpected response: %#v", resp) + return fmt.Errorf("unexpected response: %#v", resp.Object) } // ensureEndpointsContain sets the endpoints for the given service. Also removes diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/rest_to_nodes.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/rest_to_nodes.go index e25fc2aba1ee..087324749a46 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/rest_to_nodes.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/rest_to_nodes.go @@ -48,7 +48,7 @@ func (n *nodeAdaptor) Nodes() client.NodeInterface { return n } -// Create creates a new minion. +// Create creates a new node. func (n *nodeAdaptor) Create(minion *api.Node) (*api.Node, error) { return nil, errors.New("direct creation not implemented") // TODO: apiserver should expose newOperation to make this easier. @@ -71,7 +71,7 @@ func (n *nodeAdaptor) List() (*api.NodeList, error) { return obj.(*api.NodeList), nil } -// Get gets an existing minion +// Get gets an existing node. func (n *nodeAdaptor) Get(name string) (*api.Node, error) { ctx := api.NewContext() obj, err := n.storage.(apiserver.RESTGetter).Get(ctx, name) @@ -81,8 +81,13 @@ func (n *nodeAdaptor) Get(name string) (*api.Node, error) { return obj.(*api.Node), nil } -// Delete deletes an existing minion. +// Delete deletes an existing node. // TODO: implement func (n *nodeAdaptor) Delete(name string) error { return errors.New("direct deletion not implemented") } + +// Update updates an existing node. +func (n *nodeAdaptor) Update(minion *api.Node) (*api.Node, error) { + return nil, errors.New("direct update not implemented") +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/server/plugins.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/server/plugins.go new file mode 100644 index 000000000000..472adbe9246d --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/server/plugins.go @@ -0,0 +1,36 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 server + +// This file exists to force the desired plugin implementations to be linked. +// This should probably be part of some configuration fed into the build for a +// given binary target. +import ( + // Cloud providers + _ "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/aws" + _ "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/gce" + _ "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/openstack" + _ "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/ovirt" + _ "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/vagrant" + + // Admission policies + _ "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/admit" + _ "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/deny" + _ "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/limitranger" + _ "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/resourcedefaults" + _ "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/resourcequota" +) diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/server/server.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/server/server.go new file mode 100644 index 000000000000..9c95dfd4d53b --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/server/server.go @@ -0,0 +1,344 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 server does all of the work necessary to create a Kubernetes +// APIServer by binding together the API, master and APIServer infrastructure. +// It can be configured and called directly or via the hyperkube framework. +package server + +import ( + "crypto/tls" + "net" + "net/http" + "strconv" + "strings" + "time" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/admission" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" + "github.com/GoogleCloudPlatform/kubernetes/pkg/capabilities" + "github.com/GoogleCloudPlatform/kubernetes/pkg/client" + "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider" + "github.com/GoogleCloudPlatform/kubernetes/pkg/hyperkube" + "github.com/GoogleCloudPlatform/kubernetes/pkg/master" + "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" + + "github.com/coreos/go-etcd/etcd" + "github.com/golang/glog" + "github.com/spf13/pflag" +) + +// APIServer runs a kubernetes api server. +type APIServer struct { + Port int + Address util.IP + PublicAddressOverride string + ReadOnlyPort int + APIRate float32 + APIBurst int + SecurePort int + TLSCertFile string + TLSPrivateKeyFile string + APIPrefix string + StorageVersion string + CloudProvider string + CloudConfigFile string + EventTTL time.Duration + TokenAuthFile string + AuthorizationMode string + AuthorizationPolicyFile string + AdmissionControl string + AdmissionControlConfigFile string + EtcdServerList util.StringList + EtcdConfigFile string + CorsAllowedOriginList util.StringList + AllowPrivileged bool + PortalNet util.IPNet // TODO: make this a list + EnableLogsSupport bool + MasterServiceNamespace string + RuntimeConfig util.ConfigurationMap + KubeletConfig client.KubeletConfig +} + +// NewAPIServer creates a new APIServer object with default parameters +func NewAPIServer() *APIServer { + s := APIServer{ + Port: 8080, + Address: util.IP(net.ParseIP("127.0.0.1")), + ReadOnlyPort: 7080, + APIRate: 10.0, + APIBurst: 200, + SecurePort: 8443, + APIPrefix: "/api", + EventTTL: 48 * time.Hour, + AuthorizationMode: "AlwaysAllow", + AdmissionControl: "AlwaysAdmit", + EnableLogsSupport: true, + MasterServiceNamespace: api.NamespaceDefault, + + RuntimeConfig: make(util.ConfigurationMap), + KubeletConfig: client.KubeletConfig{ + Port: 10250, + EnableHttps: false, + }, + } + + return &s +} + +// NewHyperkubeServer creates a new hyperkube Server object that includes the +// description and flags. +func NewHyperkubeServer() *hyperkube.Server { + s := NewAPIServer() + + hks := hyperkube.Server{ + SimpleUsage: "apiserver", + Long: "The main API entrypoint and interface to the storage system. The API server is also the focal point for all authorization decisions.", + Run: func(_ *hyperkube.Server, args []string) error { + return s.Run(args) + }, + } + s.AddFlags(hks.Flags()) + return &hks +} + +// AddFlags adds flags for a specific APIServer to the specified FlagSet +func (s *APIServer) AddFlags(fs *pflag.FlagSet) { + // Note: the weird ""+ in below lines seems to be the only way to get gofmt to + // arrange these text blocks sensibly. Grrr. + fs.IntVar(&s.Port, "port", s.Port, ""+ + "The port to listen on. Default 8080. It is assumed that firewall rules are "+ + "set up such that this port is not reachable from outside of the cluster. It is "+ + "further assumed that port 443 on the cluster's public address is proxied to this "+ + "port. This is performed by nginx in the default setup.") + fs.Var(&s.Address, "address", "The IP address on to serve on (set to 0.0.0.0 for all interfaces)") + fs.StringVar(&s.PublicAddressOverride, "public_address_override", s.PublicAddressOverride, ""+ + "Public serving address. Read only port will be opened on this address, "+ + "and it is assumed that port 443 at this address will be proxied/redirected "+ + "to '-address':'-port'. If blank, the address in the first listed interface "+ + "will be used.") + fs.IntVar(&s.ReadOnlyPort, "read_only_port", s.ReadOnlyPort, ""+ + "The port from which to serve read-only resources. If 0, don't serve on a "+ + "read-only address. It is assumed that firewall rules are set up such that "+ + "this port is not reachable from outside of the cluster.") + fs.Float32Var(&s.APIRate, "api_rate", s.APIRate, "API rate limit as QPS for the read only port") + fs.IntVar(&s.APIBurst, "api_burst", s.APIBurst, "API burst amount for the read only port") + fs.IntVar(&s.SecurePort, "secure_port", s.SecurePort, + "The port from which to serve HTTPS with authentication and authorization. If 0, don't serve HTTPS ") + fs.StringVar(&s.TLSCertFile, "tls_cert_file", s.TLSCertFile, ""+ + "File containing x509 Certificate for HTTPS. (CA cert, if any, concatenated after server cert). "+ + "If HTTPS serving is enabled, and --tls_cert_file and --tls_private_key_file are not provided, "+ + "a self-signed certificate and key are generated for the public address and saved to /var/run/kubernetes.") + fs.StringVar(&s.TLSPrivateKeyFile, "tls_private_key_file", s.TLSPrivateKeyFile, "File containing x509 private key matching --tls_cert_file.") + fs.StringVar(&s.APIPrefix, "api_prefix", s.APIPrefix, "The prefix for API requests on the server. Default '/api'.") + fs.StringVar(&s.StorageVersion, "storage_version", s.StorageVersion, "The version to store resources with. Defaults to server preferred") + fs.StringVar(&s.CloudProvider, "cloud_provider", s.CloudProvider, "The provider for cloud services. Empty string for no provider.") + fs.StringVar(&s.CloudConfigFile, "cloud_config", s.CloudConfigFile, "The path to the cloud provider configuration file. Empty string for no configuration file.") + fs.DurationVar(&s.EventTTL, "event_ttl", s.EventTTL, "Amount of time to retain events. Default 2 days.") + fs.StringVar(&s.TokenAuthFile, "token_auth_file", s.TokenAuthFile, "If set, the file that will be used to secure the secure port of the API server via token authentication.") + fs.StringVar(&s.AuthorizationMode, "authorization_mode", s.AuthorizationMode, "Selects how to do authorization on the secure port. One of: "+strings.Join(apiserver.AuthorizationModeChoices, ",")) + fs.StringVar(&s.AuthorizationPolicyFile, "authorization_policy_file", s.AuthorizationPolicyFile, "File with authorization policy in csv format, used with --authorization_mode=ABAC, on the secure port.") + fs.StringVar(&s.AdmissionControl, "admission_control", s.AdmissionControl, "Ordered list of plug-ins to do admission control of resources into cluster. Comma-delimited list of: "+strings.Join(admission.GetPlugins(), ", ")) + fs.StringVar(&s.AdmissionControlConfigFile, "admission_control_config_file", s.AdmissionControlConfigFile, "File with admission control configuration.") + fs.Var(&s.EtcdServerList, "etcd_servers", "List of etcd servers to watch (http://ip:port), comma separated. Mutually exclusive with -etcd_config") + fs.StringVar(&s.EtcdConfigFile, "etcd_config", s.EtcdConfigFile, "The config file for the etcd client. Mutually exclusive with -etcd_servers.") + fs.Var(&s.CorsAllowedOriginList, "cors_allowed_origins", "List of allowed origins for CORS, comma separated. An allowed origin can be a regular expression to support subdomain matching. If this list is empty CORS will not be enabled.") + fs.BoolVar(&s.AllowPrivileged, "allow_privileged", s.AllowPrivileged, "If true, allow privileged containers.") + fs.Var(&s.PortalNet, "portal_net", "A CIDR notation IP range from which to assign portal IPs. This must not overlap with any IP ranges assigned to nodes for pods.") + fs.StringVar(&s.MasterServiceNamespace, "master_service_namespace", s.MasterServiceNamespace, "The namespace from which the kubernetes master services should be injected into pods") + fs.Var(&s.RuntimeConfig, "runtime_config", "A set of key=value pairs that describe runtime configuration that may be passed to the apiserver.") + client.BindKubeletClientConfigFlags(fs, &s.KubeletConfig) +} + +// TODO: Longer term we should read this from some config store, rather than a flag. +func (s *APIServer) verifyPortalFlags() { + if s.PortalNet.IP == nil { + glog.Fatal("No --portal_net specified") + } +} + +func newEtcd(etcdConfigFile string, etcdServerList util.StringList, storageVersion string) (helper tools.EtcdHelper, err error) { + var client tools.EtcdGetSet + if etcdConfigFile != "" { + client, err = etcd.NewClientFromFile(etcdConfigFile) + if err != nil { + return helper, err + } + } else { + client = etcd.NewClient(etcdServerList) + } + + return master.NewEtcdHelper(client, storageVersion) +} + +// Run runs the specified APIServer. This should never exit. +func (s *APIServer) Run(_ []string) error { + s.verifyPortalFlags() + + if (s.EtcdConfigFile != "" && len(s.EtcdServerList) != 0) || (s.EtcdConfigFile == "" && len(s.EtcdServerList) == 0) { + glog.Fatalf("specify either --etcd_servers or --etcd_config") + } + + capabilities.Initialize(capabilities.Capabilities{ + AllowPrivileged: s.AllowPrivileged, + }) + + cloud := cloudprovider.InitCloudProvider(s.CloudProvider, s.CloudConfigFile) + + kubeletClient, err := client.NewKubeletClient(&s.KubeletConfig) + if err != nil { + glog.Fatalf("Failure to start kubelet client: %v", err) + } + + _, v1beta3 := s.RuntimeConfig["api/v1beta3"] + + // TODO: expose same flags as client.BindClientConfigFlags but for a server + clientConfig := &client.Config{ + Host: net.JoinHostPort(s.Address.String(), strconv.Itoa(int(s.Port))), + Version: s.StorageVersion, + } + client, err := client.New(clientConfig) + if err != nil { + glog.Fatalf("Invalid server address: %v", err) + } + + helper, err := newEtcd(s.EtcdConfigFile, s.EtcdServerList, s.StorageVersion) + if err != nil { + glog.Fatalf("Invalid storage version or misconfigured etcd: %v", err) + } + + n := net.IPNet(s.PortalNet) + + authenticator, err := apiserver.NewAuthenticatorFromTokenFile(s.TokenAuthFile) + if err != nil { + glog.Fatalf("Invalid Authentication Config: %v", err) + } + + authorizer, err := apiserver.NewAuthorizerFromAuthorizationConfig(s.AuthorizationMode, s.AuthorizationPolicyFile) + if err != nil { + glog.Fatalf("Invalid Authorization Config: %v", err) + } + + admissionControlPluginNames := strings.Split(s.AdmissionControl, ",") + admissionController := admission.NewFromPlugins(client, admissionControlPluginNames, s.AdmissionControlConfigFile) + + config := &master.Config{ + Client: client, + Cloud: cloud, + EtcdHelper: helper, + EventTTL: s.EventTTL, + KubeletClient: kubeletClient, + PortalNet: &n, + EnableLogsSupport: s.EnableLogsSupport, + EnableUISupport: true, + EnableSwaggerSupport: true, + APIPrefix: s.APIPrefix, + CorsAllowedOriginList: s.CorsAllowedOriginList, + ReadOnlyPort: s.ReadOnlyPort, + ReadWritePort: s.Port, + PublicAddress: s.PublicAddressOverride, + Authenticator: authenticator, + Authorizer: authorizer, + AdmissionControl: admissionController, + EnableV1Beta3: v1beta3, + MasterServiceNamespace: s.MasterServiceNamespace, + } + m := master.New(config) + + // We serve on 3 ports. See docs/reaching_the_api.md + roLocation := "" + if s.ReadOnlyPort != 0 { + roLocation = net.JoinHostPort(config.PublicAddress, strconv.Itoa(config.ReadOnlyPort)) + } + secureLocation := "" + if s.SecurePort != 0 { + secureLocation = net.JoinHostPort(config.PublicAddress, strconv.Itoa(s.SecurePort)) + } + rwLocation := net.JoinHostPort(s.Address.String(), strconv.Itoa(int(s.Port))) + + // See the flag commentary to understand our assumptions when opening the read-only and read-write ports. + + if roLocation != "" { + // Default settings allow 1 read-only request per second, allow up to 20 in a burst before enforcing. + rl := util.NewTokenBucketRateLimiter(s.APIRate, s.APIBurst) + readOnlyServer := &http.Server{ + Addr: roLocation, + Handler: apiserver.RecoverPanics(apiserver.ReadOnly(apiserver.RateLimit(rl, m.InsecureHandler))), + ReadTimeout: 5 * time.Minute, + WriteTimeout: 5 * time.Minute, + MaxHeaderBytes: 1 << 20, + } + glog.Infof("Serving read-only insecurely on %s", roLocation) + go func() { + defer util.HandleCrash() + for { + if err := readOnlyServer.ListenAndServe(); err != nil { + glog.Errorf("Unable to listen for read only traffic (%v); will try again.", err) + } + time.Sleep(15 * time.Second) + } + }() + } + + if secureLocation != "" { + secureServer := &http.Server{ + Addr: secureLocation, + Handler: apiserver.RecoverPanics(m.Handler), + ReadTimeout: 5 * time.Minute, + WriteTimeout: 5 * time.Minute, + MaxHeaderBytes: 1 << 20, + TLSConfig: &tls.Config{ + // Change default from SSLv3 to TLSv1.0 (because of POODLE vulnerability) + MinVersion: tls.VersionTLS10, + // Populate PeerCertificates in requests, but don't reject connections without certificates + // This allows certificates to be validated by authenticators, while still allowing other auth types + ClientAuth: tls.RequestClientCert, + }, + } + glog.Infof("Serving securely on %s", secureLocation) + go func() { + defer util.HandleCrash() + for { + if s.TLSCertFile == "" && s.TLSPrivateKeyFile == "" { + s.TLSCertFile = "/var/run/kubernetes/apiserver.crt" + s.TLSPrivateKeyFile = "/var/run/kubernetes/apiserver.key" + if err := util.GenerateSelfSignedCert(config.PublicAddress, s.TLSCertFile, s.TLSPrivateKeyFile); err != nil { + glog.Errorf("Unable to generate self signed cert: %v", err) + } else { + glog.Infof("Using self-signed cert (%s, %s)", s.TLSCertFile, s.TLSPrivateKeyFile) + } + } + if err := secureServer.ListenAndServeTLS(s.TLSCertFile, s.TLSPrivateKeyFile); err != nil { + glog.Errorf("Unable to listen for secure (%v); will try again.", err) + } + time.Sleep(15 * time.Second) + } + }() + } + + http := &http.Server{ + Addr: rwLocation, + Handler: apiserver.RecoverPanics(m.InsecureHandler), + ReadTimeout: 5 * time.Minute, + WriteTimeout: 5 * time.Minute, + MaxHeaderBytes: 1 << 20, + } + glog.Infof("Serving insecurely on %s", rwLocation) + glog.Fatal(http.ListenAndServe()) + return nil +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/doc.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/doc.go new file mode 100644 index 000000000000..dded05f852db --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/doc.go @@ -0,0 +1,18 @@ +/* +Copyright 2015 Google Inc. All rights reserved. + +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 probe contains utilities for health probing, as well as health status information. +package probe diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/exec/exec.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/exec/exec.go new file mode 100644 index 000000000000..ac5a0f2ccc66 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/exec/exec.go @@ -0,0 +1,46 @@ +/* +Copyright 2015 Google Inc. All rights reserved. + +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 exec + +import ( + "strings" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/probe" + uexec "github.com/GoogleCloudPlatform/kubernetes/pkg/util/exec" + + "github.com/golang/glog" +) + +const defaultHealthyOutput = "ok" + +func New() ExecProber { + return ExecProber{} +} + +type ExecProber struct{} + +func (pr ExecProber) Probe(e uexec.Cmd) (probe.Status, error) { + data, err := e.CombinedOutput() + glog.V(4).Infof("health check response: %s", string(data)) + if err != nil { + return probe.Unknown, err + } + if strings.ToLower(string(data)) != defaultHealthyOutput { + return probe.Failure, nil + } + return probe.Success, nil +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/exec/exec_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/exec/exec_test.go new file mode 100644 index 000000000000..a2f21365abd4 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/exec/exec_test.go @@ -0,0 +1,69 @@ +/* +Copyright 2015 Google Inc. All rights reserved. + +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 exec + +import ( + "fmt" + "testing" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/probe" +) + +type FakeCmd struct { + out []byte + err error +} + +func (f *FakeCmd) CombinedOutput() ([]byte, error) { + return f.out, f.err +} + +func (f *FakeCmd) SetDir(dir string) {} + +type healthCheckTest struct { + expectedStatus probe.Status + expectError bool + output []byte + err error +} + +func TestExec(t *testing.T) { + prober := New() + fake := FakeCmd{} + tests := []healthCheckTest{ + // Ok + {probe.Success, false, []byte("OK"), nil}, + // Run returns error + {probe.Unknown, true, []byte("OK, NOT"), fmt.Errorf("test error")}, + // Unhealthy + {probe.Failure, false, []byte("Fail"), nil}, + } + for _, test := range tests { + fake.out = test.output + fake.err = test.err + status, err := prober.Probe(&fake) + if status != test.expectedStatus { + t.Errorf("expected %v, got %v", test.expectedStatus, status) + } + if err != nil && test.expectError == false { + t.Errorf("unexpected error: %v", err) + } + if err == nil && test.expectError == true { + t.Errorf("unexpected non-error") + } + } +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/http/http.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/http/http.go new file mode 100644 index 000000000000..e3e7898dbc21 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/http/http.go @@ -0,0 +1,73 @@ +/* +Copyright 2015 Google Inc. All rights reserved. + +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 http + +import ( + "net" + "net/http" + "net/url" + "strconv" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/probe" + + "github.com/golang/glog" +) + +func New() HTTPProber { + return HTTPProber{&http.Client{}} +} + +type HTTPProber struct { + client HTTPGetInterface +} + +// Probe returns a ProbeRunner capable of running an http check. +func (pr *HTTPProber) Probe(host string, port int, path string) (probe.Status, error) { + return DoHTTPProbe(formatURL(host, port, path), pr.client) +} + +type HTTPGetInterface interface { + Get(u string) (*http.Response, error) +} + +// DoHTTPProbe checks if a GET request to the url succeeds. +// If the HTTP response code is successful (i.e. 400 > code >= 200), it returns Success. +// If the HTTP response code is unsuccessful or HTTP communication fails, it returns Failure. +// This is exported because some other packages may want to do direct HTTP probes. +func DoHTTPProbe(url string, client HTTPGetInterface) (probe.Status, error) { + res, err := client.Get(url) + if err != nil { + glog.V(1).Infof("HTTP probe error: %v", err) + return probe.Failure, nil + } + defer res.Body.Close() + if res.StatusCode >= http.StatusOK && res.StatusCode < http.StatusBadRequest { + return probe.Success, nil + } + glog.V(1).Infof("Health check failed for %s, Response: %v", url, *res) + return probe.Failure, nil +} + +// formatURL formats a URL from args. For testability. +func formatURL(host string, port int, path string) string { + u := url.URL{ + Scheme: "http", + Host: net.JoinHostPort(host, strconv.Itoa(port)), + Path: path, + } + return u.String() +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/http/http_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/http/http_test.go new file mode 100644 index 000000000000..fd9009f6615b --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/http/http_test.go @@ -0,0 +1,85 @@ +/* +Copyright 2015 Google Inc. All rights reserved. + +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 http + +import ( + "net" + "net/http" + "net/http/httptest" + "net/url" + "strconv" + "testing" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/probe" +) + +func TestFormatURL(t *testing.T) { + testCases := []struct { + host string + port int + path string + result string + }{ + {"localhost", 93, "", "http://localhost:93"}, + {"localhost", 93, "/path", "http://localhost:93/path"}, + } + for _, test := range testCases { + url := formatURL(test.host, test.port, test.path) + if url != test.result { + t.Errorf("Expected %s, got %s", test.result, url) + } + } +} + +func TestHTTPProbeChecker(t *testing.T) { + prober := New() + testCases := []struct { + status int + health probe.Status + }{ + // The probe will be filled in below. This is primarily testing that an HTTP GET happens. + {http.StatusOK, probe.Success}, + {-1, probe.Failure}, + } + for _, test := range testCases { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(test.status) + })) + u, err := url.Parse(ts.URL) + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + host, port, err := net.SplitHostPort(u.Host) + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + p, err := strconv.Atoi(port) + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + health, err := prober.Probe(host, p, "") + if test.health == probe.Unknown && err == nil { + t.Errorf("Expected error") + } + if test.health != probe.Unknown && err != nil { + t.Errorf("Unexpected error: %v", err) + } + if health != test.health { + t.Errorf("Expected %v, got %v", test.health, health) + } + } +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/probe.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/probe.go new file mode 100644 index 000000000000..b9d1a363a38f --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/probe.go @@ -0,0 +1,37 @@ +/* +Copyright 2015 Google Inc. All rights reserved. + +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 probe + +type Status int + +// Status values must be one of these constants. +const ( + Success Status = iota + Failure + Unknown +) + +func (s Status) String() string { + switch s { + case Success: + return "success" + case Failure: + return "failure" + default: + return "unknown" + } +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/tcp/tcp.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/tcp/tcp.go new file mode 100644 index 000000000000..a452a802c749 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/tcp/tcp.go @@ -0,0 +1,52 @@ +/* +Copyright 2015 Google Inc. All rights reserved. + +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 tcp + +import ( + "net" + "strconv" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/probe" + + "github.com/golang/glog" +) + +func New() TCPProber { + return TCPProber{} +} + +type TCPProber struct{} + +func (pr TCPProber) Probe(host string, port int) (probe.Status, error) { + return DoTCPProbe(net.JoinHostPort(host, strconv.Itoa(port))) +} + +// DoTCPProbe checks that a TCP socket to the address can be opened. +// If the socket can be opened, it returns Success +// If the socket fails to open, it returns Failure. +// This is exported because some other packages may want to do direct TCP probes. +func DoTCPProbe(addr string) (probe.Status, error) { + conn, err := net.Dial("tcp", addr) + if err != nil { + return probe.Failure, nil + } + err = conn.Close() + if err != nil { + glog.Errorf("unexpected error closing health check socket: %v (%#v)", err, err) + } + return probe.Success, nil +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/tcp/tcp_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/tcp/tcp_test.go new file mode 100644 index 000000000000..bd8f61fdac0f --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/probe/tcp/tcp_test.go @@ -0,0 +1,73 @@ +/* +Copyright 2015 Google Inc. All rights reserved. + +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 tcp + +import ( + "net" + "net/http" + "net/http/httptest" + "net/url" + "strconv" + "testing" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/probe" +) + +func TestTcpHealthChecker(t *testing.T) { + prober := New() + tests := []struct { + expectedStatus probe.Status + usePort bool + expectError bool + }{ + // The probe will be filled in below. This is primarily testing that a connection is made. + {probe.Success, true, false}, + {probe.Failure, false, false}, + } + + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + })) + defer server.Close() + u, err := url.Parse(server.URL) + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + host, port, err := net.SplitHostPort(u.Host) + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + for _, test := range tests { + p, err := strconv.Atoi(port) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if !test.usePort { + p = -1 + } + status, err := prober.Probe(host, p) + if status != test.expectedStatus { + t.Errorf("expected: %v, got: %v", test.expectedStatus, status) + } + if err != nil && !test.expectError { + t.Errorf("unexpected error: %v", err) + } + if err == nil && test.expectError { + t.Errorf("unexpected non-error.") + } + } +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/proxy/loadbalancer.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/proxy/loadbalancer.go index 3ab3c1379f29..a94665383d89 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/proxy/loadbalancer.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/proxy/loadbalancer.go @@ -17,8 +17,9 @@ limitations under the License. package proxy import ( - "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "net" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" ) // LoadBalancer is an interface for distributing incoming requests to service endpoints. diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/proxy/roundrobin.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/proxy/roundrobin.go index 0e50b0879b9d..8d4adbcbbd74 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/proxy/roundrobin.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/proxy/roundrobin.go @@ -25,6 +25,7 @@ import ( "time" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util/slice" "github.com/golang/glog" ) @@ -210,14 +211,14 @@ func (lb *LoadBalancerRR) OnUpdate(endpoints []api.Endpoints) { for _, endpoint := range endpoints { existingEndpoints, exists := lb.endpointsMap[endpoint.Name] validEndpoints := filterValidEndpoints(endpoint.Endpoints) - if !exists || !reflect.DeepEqual(existingEndpoints, validEndpoints) { + if !exists || !reflect.DeepEqual(slice.SortStrings(slice.CopyStrings(existingEndpoints)), slice.SortStrings(validEndpoints)) { glog.V(3).Infof("LoadBalancerRR: Setting endpoints for %s to %+v", endpoint.Name, endpoint.Endpoints) updateServiceDetailMap(lb, endpoint.Name, validEndpoints) // On update can be called without NewService being called externally. // to be safe we will call it here. A new service will only be created // if one does not already exist. lb.NewService(endpoint.Name, api.AffinityTypeNone, 0) - lb.endpointsMap[endpoint.Name] = validEndpoints + lb.endpointsMap[endpoint.Name] = slice.ShuffleStrings(validEndpoints) // Reset the round-robin index. lb.rrIndex[endpoint.Name] = 0 diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/proxy/roundrobin_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/proxy/roundrobin_test.go index bb9f54b030fc..29bac114fbc7 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/proxy/roundrobin_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/proxy/roundrobin_test.go @@ -75,7 +75,7 @@ func expectEndpoint(t *testing.T, loadBalancer *LoadBalancerRR, service string, t.Errorf("Didn't find a service for %s, expected %s, failed with: %v", service, expected, err) } if endpoint != expected { - t.Errorf("Didn't get expected endpoint for service %s, expected %s, got: %s", service, expected, endpoint) + t.Errorf("Didn't get expected endpoint for service %s client %v, expected %s, got: %s", service, netaddr, expected, endpoint) } } @@ -109,10 +109,11 @@ func TestLoadBalanceWorksWithMultipleEndpoints(t *testing.T) { Endpoints: []string{"endpoint:1", "endpoint:2", "endpoint:3"}, } loadBalancer.OnUpdate(endpoints) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", nil) - expectEndpoint(t, loadBalancer, "foo", "endpoint:2", nil) - expectEndpoint(t, loadBalancer, "foo", "endpoint:3", nil) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", nil) + shuffledEndpoints := loadBalancer.endpointsMap["foo"] + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[0], nil) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[1], nil) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[2], nil) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[0], nil) } func TestLoadBalanceWorksWithMultipleEndpointsAndUpdates(t *testing.T) { @@ -127,21 +128,23 @@ func TestLoadBalanceWorksWithMultipleEndpointsAndUpdates(t *testing.T) { Endpoints: []string{"endpoint:1", "endpoint:2", "endpoint:3"}, } loadBalancer.OnUpdate(endpoints) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", nil) - expectEndpoint(t, loadBalancer, "foo", "endpoint:2", nil) - expectEndpoint(t, loadBalancer, "foo", "endpoint:3", nil) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", nil) - expectEndpoint(t, loadBalancer, "foo", "endpoint:2", nil) + shuffledEndpoints := loadBalancer.endpointsMap["foo"] + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[0], nil) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[1], nil) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[2], nil) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[0], nil) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[1], nil) // Then update the configuration with one fewer endpoints, make sure // we start in the beginning again endpoints[0] = api.Endpoints{ObjectMeta: api.ObjectMeta{Name: "foo"}, Endpoints: []string{"endpoint:8", "endpoint:9"}, } loadBalancer.OnUpdate(endpoints) - expectEndpoint(t, loadBalancer, "foo", "endpoint:8", nil) - expectEndpoint(t, loadBalancer, "foo", "endpoint:9", nil) - expectEndpoint(t, loadBalancer, "foo", "endpoint:8", nil) - expectEndpoint(t, loadBalancer, "foo", "endpoint:9", nil) + shuffledEndpoints = loadBalancer.endpointsMap["foo"] + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[0], nil) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[1], nil) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[0], nil) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[1], nil) // Clear endpoints endpoints[0] = api.Endpoints{ObjectMeta: api.ObjectMeta{Name: "foo"}, Endpoints: []string{}} loadBalancer.OnUpdate(endpoints) @@ -168,17 +171,19 @@ func TestLoadBalanceWorksWithServiceRemoval(t *testing.T) { Endpoints: []string{"endpoint:4", "endpoint:5"}, } loadBalancer.OnUpdate(endpoints) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", nil) - expectEndpoint(t, loadBalancer, "foo", "endpoint:2", nil) - expectEndpoint(t, loadBalancer, "foo", "endpoint:3", nil) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", nil) - expectEndpoint(t, loadBalancer, "foo", "endpoint:2", nil) - - expectEndpoint(t, loadBalancer, "bar", "endpoint:4", nil) - expectEndpoint(t, loadBalancer, "bar", "endpoint:5", nil) - expectEndpoint(t, loadBalancer, "bar", "endpoint:4", nil) - expectEndpoint(t, loadBalancer, "bar", "endpoint:5", nil) - expectEndpoint(t, loadBalancer, "bar", "endpoint:4", nil) + shuffledFooEndpoints := loadBalancer.endpointsMap["foo"] + expectEndpoint(t, loadBalancer, "foo", shuffledFooEndpoints[0], nil) + expectEndpoint(t, loadBalancer, "foo", shuffledFooEndpoints[1], nil) + expectEndpoint(t, loadBalancer, "foo", shuffledFooEndpoints[2], nil) + expectEndpoint(t, loadBalancer, "foo", shuffledFooEndpoints[0], nil) + expectEndpoint(t, loadBalancer, "foo", shuffledFooEndpoints[1], nil) + + shuffledBarEndpoints := loadBalancer.endpointsMap["bar"] + expectEndpoint(t, loadBalancer, "bar", shuffledBarEndpoints[0], nil) + expectEndpoint(t, loadBalancer, "bar", shuffledBarEndpoints[1], nil) + expectEndpoint(t, loadBalancer, "bar", shuffledBarEndpoints[0], nil) + expectEndpoint(t, loadBalancer, "bar", shuffledBarEndpoints[1], nil) + expectEndpoint(t, loadBalancer, "bar", shuffledBarEndpoints[0], nil) // Then update the configuration by removing foo loadBalancer.OnUpdate(endpoints[1:]) @@ -188,10 +193,10 @@ func TestLoadBalanceWorksWithServiceRemoval(t *testing.T) { } // but bar is still there, and we continue RR from where we left off. - expectEndpoint(t, loadBalancer, "bar", "endpoint:5", nil) - expectEndpoint(t, loadBalancer, "bar", "endpoint:4", nil) - expectEndpoint(t, loadBalancer, "bar", "endpoint:5", nil) - expectEndpoint(t, loadBalancer, "bar", "endpoint:4", nil) + expectEndpoint(t, loadBalancer, "bar", shuffledBarEndpoints[1], nil) + expectEndpoint(t, loadBalancer, "bar", shuffledBarEndpoints[0], nil) + expectEndpoint(t, loadBalancer, "bar", shuffledBarEndpoints[1], nil) + expectEndpoint(t, loadBalancer, "bar", shuffledBarEndpoints[0], nil) } func TestStickyLoadBalanceWorksWithSingleEndpoint(t *testing.T) { @@ -232,14 +237,15 @@ func TestStickyLoadBalanaceWorksWithMultipleEndpoints(t *testing.T) { Endpoints: []string{"endpoint:1", "endpoint:2", "endpoint:3"}, } loadBalancer.OnUpdate(endpoints) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", client1) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", client1) - expectEndpoint(t, loadBalancer, "foo", "endpoint:2", client2) - expectEndpoint(t, loadBalancer, "foo", "endpoint:2", client2) - expectEndpoint(t, loadBalancer, "foo", "endpoint:3", client3) - expectEndpoint(t, loadBalancer, "foo", "endpoint:3", client3) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", client1) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", client1) + shuffledEndpoints := loadBalancer.endpointsMap["foo"] + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[0], client1) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[0], client1) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[1], client2) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[1], client2) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[2], client3) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[2], client3) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[0], client1) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[0], client1) } func TestStickyLoadBalanaceWorksWithMultipleEndpointsStickyNone(t *testing.T) { @@ -259,14 +265,15 @@ func TestStickyLoadBalanaceWorksWithMultipleEndpointsStickyNone(t *testing.T) { Endpoints: []string{"endpoint:1", "endpoint:2", "endpoint:3"}, } loadBalancer.OnUpdate(endpoints) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", client1) - expectEndpoint(t, loadBalancer, "foo", "endpoint:2", client1) - expectEndpoint(t, loadBalancer, "foo", "endpoint:3", client2) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", client2) - expectEndpoint(t, loadBalancer, "foo", "endpoint:2", client3) - expectEndpoint(t, loadBalancer, "foo", "endpoint:3", client3) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", client1) - expectEndpoint(t, loadBalancer, "foo", "endpoint:2", client1) + shuffledEndpoints := loadBalancer.endpointsMap["foo"] + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[0], client1) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[1], client1) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[2], client2) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[0], client2) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[1], client3) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[2], client3) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[0], client1) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[1], client1) } func TestStickyLoadBalanaceWorksWithMultipleEndpointsRemoveOne(t *testing.T) { @@ -289,32 +296,45 @@ func TestStickyLoadBalanaceWorksWithMultipleEndpointsRemoveOne(t *testing.T) { Endpoints: []string{"endpoint:1", "endpoint:2", "endpoint:3"}, } loadBalancer.OnUpdate(endpoints) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", client1) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", client1) - expectEndpoint(t, loadBalancer, "foo", "endpoint:2", client2) - expectEndpoint(t, loadBalancer, "foo", "endpoint:2", client2) - expectEndpoint(t, loadBalancer, "foo", "endpoint:3", client3) + shuffledEndpoints := loadBalancer.endpointsMap["foo"] + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[0], client1) + client1Endpoint := shuffledEndpoints[0] + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[0], client1) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[1], client2) + client2Endpoint := shuffledEndpoints[1] + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[1], client2) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[2], client3) + client3Endpoint := shuffledEndpoints[2] endpoints[0] = api.Endpoints{ ObjectMeta: api.ObjectMeta{Name: "foo"}, Endpoints: []string{"endpoint:1", "endpoint:2"}, } loadBalancer.OnUpdate(endpoints) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", client1) - expectEndpoint(t, loadBalancer, "foo", "endpoint:2", client2) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", client3) + shuffledEndpoints = loadBalancer.endpointsMap["foo"] + if client1Endpoint == "endpoint:3" { + client1Endpoint = shuffledEndpoints[0] + } else if client2Endpoint == "endpoint:3" { + client2Endpoint = shuffledEndpoints[0] + } else if client3Endpoint == "endpoint:3" { + client3Endpoint = shuffledEndpoints[0] + } + expectEndpoint(t, loadBalancer, "foo", client1Endpoint, client1) + expectEndpoint(t, loadBalancer, "foo", client2Endpoint, client2) + expectEndpoint(t, loadBalancer, "foo", client3Endpoint, client3) endpoints[0] = api.Endpoints{ ObjectMeta: api.ObjectMeta{Name: "foo"}, Endpoints: []string{"endpoint:1", "endpoint:2", "endpoint:4"}, } loadBalancer.OnUpdate(endpoints) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", client1) - expectEndpoint(t, loadBalancer, "foo", "endpoint:2", client2) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", client3) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", client4) - expectEndpoint(t, loadBalancer, "foo", "endpoint:2", client5) - expectEndpoint(t, loadBalancer, "foo", "endpoint:4", client6) + shuffledEndpoints = loadBalancer.endpointsMap["foo"] + expectEndpoint(t, loadBalancer, "foo", client1Endpoint, client1) + expectEndpoint(t, loadBalancer, "foo", client2Endpoint, client2) + expectEndpoint(t, loadBalancer, "foo", client3Endpoint, client3) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[0], client4) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[1], client5) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[2], client6) } func TestStickyLoadBalanceWorksWithMultipleEndpointsAndUpdates(t *testing.T) { @@ -334,24 +354,26 @@ func TestStickyLoadBalanceWorksWithMultipleEndpointsAndUpdates(t *testing.T) { Endpoints: []string{"endpoint:1", "endpoint:2", "endpoint:3"}, } loadBalancer.OnUpdate(endpoints) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", client1) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", client1) - expectEndpoint(t, loadBalancer, "foo", "endpoint:2", client2) - expectEndpoint(t, loadBalancer, "foo", "endpoint:2", client2) - expectEndpoint(t, loadBalancer, "foo", "endpoint:3", client3) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", client1) - expectEndpoint(t, loadBalancer, "foo", "endpoint:2", client2) + shuffledEndpoints := loadBalancer.endpointsMap["foo"] + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[0], client1) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[0], client1) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[1], client2) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[1], client2) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[2], client3) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[0], client1) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[1], client2) // Then update the configuration with one fewer endpoints, make sure // we start in the beginning again endpoints[0] = api.Endpoints{ObjectMeta: api.ObjectMeta{Name: "foo"}, Endpoints: []string{"endpoint:4", "endpoint:5"}, } loadBalancer.OnUpdate(endpoints) - expectEndpoint(t, loadBalancer, "foo", "endpoint:4", client1) - expectEndpoint(t, loadBalancer, "foo", "endpoint:5", client2) - expectEndpoint(t, loadBalancer, "foo", "endpoint:4", client1) - expectEndpoint(t, loadBalancer, "foo", "endpoint:5", client2) - expectEndpoint(t, loadBalancer, "foo", "endpoint:5", client2) + shuffledEndpoints = loadBalancer.endpointsMap["foo"] + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[0], client1) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[1], client2) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[0], client1) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[1], client2) + expectEndpoint(t, loadBalancer, "foo", shuffledEndpoints[1], client2) // Clear endpoints endpoints[0] = api.Endpoints{ObjectMeta: api.ObjectMeta{Name: "foo"}, Endpoints: []string{}} @@ -384,19 +406,21 @@ func TestStickyLoadBalanceWorksWithServiceRemoval(t *testing.T) { Endpoints: []string{"endpoint:4", "endpoint:5"}, } loadBalancer.OnUpdate(endpoints) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", client1) - expectEndpoint(t, loadBalancer, "foo", "endpoint:2", client2) - expectEndpoint(t, loadBalancer, "foo", "endpoint:3", client3) - expectEndpoint(t, loadBalancer, "foo", "endpoint:3", client3) - expectEndpoint(t, loadBalancer, "foo", "endpoint:1", client1) - expectEndpoint(t, loadBalancer, "foo", "endpoint:2", client2) - - expectEndpoint(t, loadBalancer, "bar", "endpoint:4", client1) - expectEndpoint(t, loadBalancer, "bar", "endpoint:5", client2) - expectEndpoint(t, loadBalancer, "bar", "endpoint:4", client1) - expectEndpoint(t, loadBalancer, "bar", "endpoint:5", client2) - expectEndpoint(t, loadBalancer, "bar", "endpoint:4", client1) - expectEndpoint(t, loadBalancer, "bar", "endpoint:4", client1) + shuffledFooEndpoints := loadBalancer.endpointsMap["foo"] + expectEndpoint(t, loadBalancer, "foo", shuffledFooEndpoints[0], client1) + expectEndpoint(t, loadBalancer, "foo", shuffledFooEndpoints[1], client2) + expectEndpoint(t, loadBalancer, "foo", shuffledFooEndpoints[2], client3) + expectEndpoint(t, loadBalancer, "foo", shuffledFooEndpoints[2], client3) + expectEndpoint(t, loadBalancer, "foo", shuffledFooEndpoints[0], client1) + expectEndpoint(t, loadBalancer, "foo", shuffledFooEndpoints[1], client2) + + shuffledBarEndpoints := loadBalancer.endpointsMap["bar"] + expectEndpoint(t, loadBalancer, "foo", shuffledFooEndpoints[0], client1) + expectEndpoint(t, loadBalancer, "foo", shuffledFooEndpoints[1], client2) + expectEndpoint(t, loadBalancer, "foo", shuffledFooEndpoints[0], client1) + expectEndpoint(t, loadBalancer, "foo", shuffledFooEndpoints[1], client2) + expectEndpoint(t, loadBalancer, "foo", shuffledFooEndpoints[0], client1) + expectEndpoint(t, loadBalancer, "foo", shuffledFooEndpoints[0], client1) // Then update the configuration by removing foo loadBalancer.OnUpdate(endpoints[1:]) @@ -406,10 +430,11 @@ func TestStickyLoadBalanceWorksWithServiceRemoval(t *testing.T) { } // but bar is still there, and we continue RR from where we left off. - expectEndpoint(t, loadBalancer, "bar", "endpoint:4", client1) - expectEndpoint(t, loadBalancer, "bar", "endpoint:5", client2) - expectEndpoint(t, loadBalancer, "bar", "endpoint:4", client1) - expectEndpoint(t, loadBalancer, "bar", "endpoint:5", client2) - expectEndpoint(t, loadBalancer, "bar", "endpoint:4", client1) - expectEndpoint(t, loadBalancer, "bar", "endpoint:4", client1) + shuffledBarEndpoints = loadBalancer.endpointsMap["bar"] + expectEndpoint(t, loadBalancer, "bar", shuffledBarEndpoints[0], client1) + expectEndpoint(t, loadBalancer, "bar", shuffledBarEndpoints[1], client2) + expectEndpoint(t, loadBalancer, "bar", shuffledBarEndpoints[0], client1) + expectEndpoint(t, loadBalancer, "bar", shuffledBarEndpoints[1], client2) + expectEndpoint(t, loadBalancer, "bar", shuffledBarEndpoints[0], client1) + expectEndpoint(t, loadBalancer, "bar", shuffledBarEndpoints[0], client1) } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/controller/rest.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/controller/rest.go index 350985f1f2a0..5171914af593 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/controller/rest.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/controller/rest.go @@ -18,7 +18,6 @@ package controller import ( "fmt" - "time" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" @@ -38,17 +37,15 @@ type PodLister interface { // REST implements apiserver.RESTStorage for the replication controller service. type REST struct { - registry Registry - podLister PodLister - pollPeriod time.Duration + registry Registry + podLister PodLister } // NewREST returns a new apiserver.RESTStorage for the given registry and PodLister. func NewREST(registry Registry, podLister PodLister) *REST { return &REST{ - registry: registry, - podLister: podLister, - pollPeriod: time.Second * 10, + registry: registry, + podLister: podLister, } } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/controller/rest_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/controller/rest_test.go index 585a956c0ce6..dc5455959b12 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/controller/rest_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/controller/rest_test.go @@ -143,7 +143,7 @@ func TestControllerDecode(t *testing.T) { func TestControllerParsing(t *testing.T) { expectedController := api.ReplicationController{ ObjectMeta: api.ObjectMeta{ - Name: "nginxController", + Name: "nginx-controller", Labels: map[string]string{ "name": "nginx", }, @@ -243,9 +243,8 @@ func TestCreateController(t *testing.T) { }, } storage := REST{ - registry: &mockRegistry, - podLister: &mockPodRegistry, - pollPeriod: time.Millisecond * 1, + registry: &mockRegistry, + podLister: &mockPodRegistry, } controller := &api.ReplicationController{ ObjectMeta: api.ObjectMeta{Name: "test"}, @@ -278,9 +277,8 @@ func TestCreateController(t *testing.T) { func TestControllerStorageValidatesCreate(t *testing.T) { mockRegistry := registrytest.ControllerRegistry{} storage := REST{ - registry: &mockRegistry, - podLister: nil, - pollPeriod: time.Millisecond * 1, + registry: &mockRegistry, + podLister: nil, } failureCases := map[string]api.ReplicationController{ "empty ID": { @@ -309,9 +307,8 @@ func TestControllerStorageValidatesCreate(t *testing.T) { func TestControllerStorageValidatesUpdate(t *testing.T) { mockRegistry := registrytest.ControllerRegistry{} storage := REST{ - registry: &mockRegistry, - podLister: nil, - pollPeriod: time.Millisecond * 1, + registry: &mockRegistry, + podLister: nil, } failureCases := map[string]api.ReplicationController{ "empty ID": { diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/etcd/etcd.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/etcd/etcd.go index d372f75bea48..d2bd576cb529 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/etcd/etcd.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/etcd/etcd.go @@ -347,7 +347,17 @@ func (r *Registry) WatchControllers(ctx api.Context, label, field labels.Selecto } match := label.Matches(labels.Set(controller.Labels)) if match { - pods, _ := r.ListPods(ctx, labels.Set(controller.Spec.Selector).AsSelector()) + pods, err := r.ListPods(ctx, labels.Set(controller.Spec.Selector).AsSelector()) + if err != nil { + glog.Warningf("Error listing pods: %v", err) + // No object that's useable so drop it on the floor + return false + } + if pods == nil { + glog.Warningf("Pods list is nil. This should never happen...") + // No object that's useable so drop it on the floor + return false + } controller.Status.Replicas = len(pods.Items) } return match diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/limitrange/doc.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/limitrange/doc.go new file mode 100644 index 000000000000..7619321aca35 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/limitrange/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 limitrange provides Registry interface and it's REST +// implementation for storing LimitRange api objects. +package limitrange diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/limitrange/registry.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/limitrange/registry.go new file mode 100644 index 000000000000..e08d2b0d8b64 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/limitrange/registry.go @@ -0,0 +1,48 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 limitrange + +import ( + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" + etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" + "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" +) + +// registry implements custom changes to generic.Etcd. +type registry struct { + *etcdgeneric.Etcd +} + +// NewEtcdRegistry returns a registry which will store LimitRange in the given helper +func NewEtcdRegistry(h tools.EtcdHelper) generic.Registry { + return registry{ + Etcd: &etcdgeneric.Etcd{ + NewFunc: func() runtime.Object { return &api.LimitRange{} }, + NewListFunc: func() runtime.Object { return &api.LimitRangeList{} }, + EndpointName: "limitranges", + KeyRootFunc: func(ctx api.Context) string { + return etcdgeneric.NamespaceKeyRootFunc(ctx, "/registry/limitranges") + }, + KeyFunc: func(ctx api.Context, id string) (string, error) { + return etcdgeneric.NamespaceKeyFunc(ctx, "/registry/limitranges", id) + }, + Helper: h, + }, + } +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/limitrange/registry_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/limitrange/registry_test.go new file mode 100644 index 000000000000..4c081f8d0245 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/limitrange/registry_test.go @@ -0,0 +1,121 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 limitrange + +import ( + "reflect" + "testing" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" + "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" + etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" + "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" + + "github.com/coreos/go-etcd/etcd" +) + +func NewTestLimitRangeEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, generic.Registry) { + f := tools.NewFakeEtcdClient(t) + f.TestIndex = true + h := tools.EtcdHelper{f, testapi.Codec(), tools.RuntimeVersionAdapter{testapi.MetadataAccessor()}} + return f, NewEtcdRegistry(h) +} + +func TestLimitRangeCreate(t *testing.T) { + limitRange := &api.LimitRange{ + ObjectMeta: api.ObjectMeta{ + Name: "abc", + Namespace: "foo", + }, + Spec: api.LimitRangeSpec{ + Limits: []api.LimitRangeItem{ + { + Type: api.LimitTypePod, + Max: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100"), + api.ResourceMemory: resource.MustParse("10000"), + }, + Min: api.ResourceList{ + api.ResourceCPU: resource.MustParse("0"), + api.ResourceMemory: resource.MustParse("100"), + }, + }, + }, + }, + } + + nodeWithLimitRange := tools.EtcdResponseWithError{ + R: &etcd.Response{ + Node: &etcd.Node{ + Value: runtime.EncodeOrDie(testapi.Codec(), limitRange), + ModifiedIndex: 1, + CreatedIndex: 1, + }, + }, + E: nil, + } + + emptyNode := tools.EtcdResponseWithError{ + R: &etcd.Response{}, + E: tools.EtcdErrorNotFound, + } + + ctx := api.NewDefaultContext() + key := "foo" + path, err := etcdgeneric.NamespaceKeyFunc(ctx, "/registry/limitranges", key) + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + + table := map[string]struct { + existing tools.EtcdResponseWithError + expect tools.EtcdResponseWithError + toCreate runtime.Object + errOK func(error) bool + }{ + "normal": { + existing: emptyNode, + expect: nodeWithLimitRange, + toCreate: limitRange, + errOK: func(err error) bool { return err == nil }, + }, + "preExisting": { + existing: nodeWithLimitRange, + expect: nodeWithLimitRange, + toCreate: limitRange, + errOK: errors.IsAlreadyExists, + }, + } + + for name, item := range table { + fakeClient, registry := NewTestLimitRangeEtcdRegistry(t) + fakeClient.Data[path] = item.existing + err := registry.Create(ctx, key, item.toCreate) + if !item.errOK(err) { + t.Errorf("%v: unexpected error: %v", name, err) + } + + if e, a := item.expect, fakeClient.Data[path]; !reflect.DeepEqual(e, a) { + t.Errorf("%v:\n%s", name, util.ObjectDiff(e, a)) + } + } +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/limitrange/rest.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/limitrange/rest.go new file mode 100644 index 000000000000..f5eaaa1a71d6 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/limitrange/rest.go @@ -0,0 +1,159 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 limitrange + +import ( + "fmt" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation" + "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" + "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" + "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" + "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" + "github.com/GoogleCloudPlatform/kubernetes/pkg/watch" +) + +// REST provides the RESTStorage access patterns to work with LimitRange objects. +type REST struct { + registry generic.Registry +} + +// NewREST returns a new REST. You must use a registry created by +// NewEtcdRegistry unless you're testing. +func NewREST(registry generic.Registry) *REST { + return &REST{ + registry: registry, + } +} + +// Create a LimitRange object +func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RESTResult, error) { + limitRange, ok := obj.(*api.LimitRange) + if !ok { + return nil, fmt.Errorf("invalid object type") + } + + if !api.ValidNamespace(ctx, &limitRange.ObjectMeta) { + return nil, errors.NewConflict("limitRange", limitRange.Namespace, fmt.Errorf("LimitRange.Namespace does not match the provided context")) + } + + if len(limitRange.Name) == 0 { + limitRange.Name = string(util.NewUUID()) + } + + if errs := validation.ValidateLimitRange(limitRange); len(errs) > 0 { + return nil, errors.NewInvalid("limitRange", limitRange.Name, errs) + } + api.FillObjectMetaSystemFields(ctx, &limitRange.ObjectMeta) + + return apiserver.MakeAsync(func() (runtime.Object, error) { + err := rs.registry.Create(ctx, limitRange.Name, limitRange) + if err != nil { + return nil, err + } + return rs.registry.Get(ctx, limitRange.Name) + }), nil +} + +// Update updates a LimitRange object. +func (rs *REST) Update(ctx api.Context, obj runtime.Object) (<-chan apiserver.RESTResult, error) { + limitRange, ok := obj.(*api.LimitRange) + if !ok { + return nil, fmt.Errorf("invalid object type") + } + + if !api.ValidNamespace(ctx, &limitRange.ObjectMeta) { + return nil, errors.NewConflict("limitRange", limitRange.Namespace, fmt.Errorf("LimitRange.Namespace does not match the provided context")) + } + + oldObj, err := rs.registry.Get(ctx, limitRange.Name) + if err != nil { + return nil, err + } + + editLimitRange := oldObj.(*api.LimitRange) + + // set the editable fields on the existing object + editLimitRange.Labels = limitRange.Labels + editLimitRange.ResourceVersion = limitRange.ResourceVersion + editLimitRange.Annotations = limitRange.Annotations + editLimitRange.Spec = limitRange.Spec + + if errs := validation.ValidateLimitRange(editLimitRange); len(errs) > 0 { + return nil, errors.NewInvalid("limitRange", editLimitRange.Name, errs) + } + + return apiserver.MakeAsync(func() (runtime.Object, error) { + err := rs.registry.Update(ctx, editLimitRange.Name, editLimitRange) + if err != nil { + return nil, err + } + return rs.registry.Get(ctx, editLimitRange.Name) + }), nil +} + +// Delete deletes the LimitRange with the specified name +func (rs *REST) Delete(ctx api.Context, name string) (<-chan apiserver.RESTResult, error) { + obj, err := rs.registry.Get(ctx, name) + if err != nil { + return nil, err + } + _, ok := obj.(*api.LimitRange) + if !ok { + return nil, fmt.Errorf("invalid object type") + } + return apiserver.MakeAsync(func() (runtime.Object, error) { + return &api.Status{Status: api.StatusSuccess}, rs.registry.Delete(ctx, name) + }), nil +} + +// Get gets a LimitRange with the specified name +func (rs *REST) Get(ctx api.Context, name string) (runtime.Object, error) { + obj, err := rs.registry.Get(ctx, name) + if err != nil { + return nil, err + } + limitRange, ok := obj.(*api.LimitRange) + if !ok { + return nil, fmt.Errorf("invalid object type") + } + return limitRange, err +} + +func (rs *REST) getAttrs(obj runtime.Object) (objLabels, objFields labels.Set, err error) { + return labels.Set{}, labels.Set{}, nil +} + +func (rs *REST) List(ctx api.Context, label, field labels.Selector) (runtime.Object, error) { + return rs.registry.List(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs}) +} + +func (rs *REST) Watch(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { + return rs.registry.Watch(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs}, resourceVersion) +} + +// New returns a new api.LimitRange +func (*REST) New() runtime.Object { + return &api.LimitRange{} +} + +func (*REST) NewList() runtime.Object { + return &api.LimitRangeList{} +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/doc.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/limitrange/rest_test.go similarity index 83% rename from Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/doc.go rename to Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/limitrange/rest_test.go index 6c5580a13015..f003a69184a5 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/health/doc.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/limitrange/rest_test.go @@ -14,5 +14,4 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package health contains utilities for health checking, as well as health status information. -package health +package limitrange diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion/healthy_registry.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion/healthy_registry.go deleted file mode 100644 index a6d32607e086..000000000000 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion/healthy_registry.go +++ /dev/null @@ -1,125 +0,0 @@ -/* -Copyright 2014 Google Inc. All rights reserved. - -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 minion - -import ( - "sync" - "time" - - "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - "github.com/GoogleCloudPlatform/kubernetes/pkg/client" - "github.com/GoogleCloudPlatform/kubernetes/pkg/health" - "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" - "github.com/GoogleCloudPlatform/kubernetes/pkg/util" - "github.com/GoogleCloudPlatform/kubernetes/pkg/watch" - - "github.com/golang/glog" -) - -type HealthyRegistry struct { - delegate Registry - client client.KubeletHealthChecker - cache util.TimeCache -} - -func NewHealthyRegistry(delegate Registry, client client.KubeletHealthChecker, clock util.Clock, ttl time.Duration) Registry { - h := &HealthyRegistry{ - delegate: delegate, - client: client, - } - h.cache = util.NewTimeCache(clock, ttl, h.doCheck) - return h -} - -func (r *HealthyRegistry) GetMinion(ctx api.Context, minionID string) (*api.Node, error) { - minion, err := r.delegate.GetMinion(ctx, minionID) - if err != nil { - return nil, err - } - return r.checkMinion(minion), nil -} - -func (r *HealthyRegistry) DeleteMinion(ctx api.Context, minionID string) error { - return r.delegate.DeleteMinion(ctx, minionID) -} - -func (r *HealthyRegistry) CreateMinion(ctx api.Context, minion *api.Node) error { - return r.delegate.CreateMinion(ctx, minion) -} - -func (r *HealthyRegistry) UpdateMinion(ctx api.Context, minion *api.Node) error { - return r.delegate.UpdateMinion(ctx, minion) -} - -func (r *HealthyRegistry) ListMinions(ctx api.Context) (currentMinions *api.NodeList, err error) { - list, err := r.delegate.ListMinions(ctx) - if err != nil { - return nil, err - } - - // In case the cache is empty, health check in parallel instead of serially. - var wg sync.WaitGroup - wg.Add(len(list.Items)) - for i := range list.Items { - go func(i int) { - list.Items[i] = *r.checkMinion(&list.Items[i]) - wg.Done() - }(i) - } - wg.Wait() - return list, nil -} - -func (r *HealthyRegistry) WatchMinions(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { - w, err := r.delegate.WatchMinions(ctx, label, field, resourceVersion) - if err != nil { - return nil, err - } - return watch.Filter(w, watch.FilterFunc(func(in watch.Event) (watch.Event, bool) { - if node, ok := in.Object.(*api.Node); ok && node != nil { - in.Object = r.checkMinion(node) - } - return in, true - })), nil -} - -func (r *HealthyRegistry) checkMinion(node *api.Node) *api.Node { - condition := r.cache.Get(node.Name).(api.NodeConditionStatus) - // TODO: distinguish other conditions like Reachable/Live, and begin storing this - // data on nodes directly via sync loops. - node.Status.Conditions = append(node.Status.Conditions, api.NodeCondition{ - Kind: api.NodeReady, - Status: condition, - }) - return node -} - -// This is called to fill the cache. -func (r *HealthyRegistry) doCheck(key string) util.T { - var nodeStatus api.NodeConditionStatus - switch status, err := r.client.HealthCheck(key); { - case err != nil: - glog.V(2).Infof("HealthyRegistry: node %q health check error: %v", key, err) - nodeStatus = api.ConditionUnknown - case status == health.Unhealthy: - nodeStatus = api.ConditionNone - default: - nodeStatus = api.ConditionFull - } - glog.V(3).Infof("HealthyRegistry: node %q status was %q", key, nodeStatus) - return nodeStatus -} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion/healthy_registry_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion/healthy_registry_test.go deleted file mode 100644 index ba4ea3bb531a..000000000000 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion/healthy_registry_test.go +++ /dev/null @@ -1,114 +0,0 @@ -/* -Copyright 2014 Google Inc. All rights reserved. - -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 minion - -import ( - "reflect" - "testing" - "time" - - "github.com/GoogleCloudPlatform/kubernetes/pkg/api" - "github.com/GoogleCloudPlatform/kubernetes/pkg/health" - "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" - "github.com/GoogleCloudPlatform/kubernetes/pkg/util" -) - -type alwaysYes struct{} - -func (alwaysYes) HealthCheck(host string) (health.Status, error) { - return health.Healthy, nil -} - -func TestBasicDelegation(t *testing.T) { - ctx := api.NewContext() - mockMinionRegistry := registrytest.NewMinionRegistry([]string{"m1", "m2", "m3"}, api.NodeResources{}) - healthy := NewHealthyRegistry( - mockMinionRegistry, - alwaysYes{}, - &util.FakeClock{}, - 60*time.Second, - ) - list, err := healthy.ListMinions(ctx) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - if !reflect.DeepEqual(list, &mockMinionRegistry.Minions) { - t.Errorf("Expected %v, Got %v", mockMinionRegistry.Minions, list) - } - err = healthy.CreateMinion(ctx, &api.Node{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - }) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - minion, err := healthy.GetMinion(ctx, "m1") - if err != nil { - t.Errorf("unexpected error: %v", err) - } - if minion == nil { - t.Errorf("Unexpected absence of 'm1'") - } - minion, err = healthy.GetMinion(ctx, "m5") - if err == nil { - t.Errorf("unexpected non-error") - } - if minion != nil { - t.Errorf("Unexpected presence of 'm5'") - } -} - -type notMinion struct { - minion string -} - -func (n *notMinion) HealthCheck(host string) (health.Status, error) { - if host != n.minion { - return health.Healthy, nil - } else { - return health.Unhealthy, nil - } -} - -func TestFiltering(t *testing.T) { - ctx := api.NewContext() - mockMinionRegistry := registrytest.NewMinionRegistry([]string{"m1", "m2", "m3"}, api.NodeResources{}) - healthy := NewHealthyRegistry( - mockMinionRegistry, - ¬Minion{minion: "m1"}, - &util.FakeClock{}, - 60*time.Second, - ) - expected := []string{"m1", "m2", "m3"} - list, err := healthy.ListMinions(ctx) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - expectedMinions := registrytest.MakeMinionList(expected, api.NodeResources{}) - expectedMinions.Items[0].Status.Conditions = []api.NodeCondition{{Kind: api.NodeReady, Status: api.ConditionNone}} - expectedMinions.Items[1].Status.Conditions = []api.NodeCondition{{Kind: api.NodeReady, Status: api.ConditionFull}} - expectedMinions.Items[2].Status.Conditions = []api.NodeCondition{{Kind: api.NodeReady, Status: api.ConditionFull}} - if !reflect.DeepEqual(list, expectedMinions) { - t.Errorf("Expected %v, Got %v", expected, list) - } - minion, err := healthy.GetMinion(ctx, "m1") - if err != nil { - t.Errorf("unexpected error: %v", err) - } - if minion == nil { - t.Errorf("Unexpected empty 'm1'") - } -} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion/rest.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion/rest.go index 8415a5968fff..58f1450cfc1a 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion/rest.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion/rest.go @@ -122,12 +122,18 @@ func (rs *REST) Update(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE // Clear out the self link, if specified, since it's not in the registry either. minion.SelfLink = "" - // TODO: GetMinion will health check the minion, but we shouldn't require the minion to be - // running for updating labels. oldMinion, err := rs.registry.GetMinion(ctx, minion.Name) if err != nil { return nil, err } + + // This is hacky, but minion HostIP has been moved from spec to status since v1beta2. When updating + // minion from older client, HostIP will be lost. Fix it here temporarily until we strip out status + // info from user input. + if minion.Status.HostIP == "" { + minion.Status.HostIP = oldMinion.Status.HostIP + } + if errs := validation.ValidateMinionUpdate(oldMinion, minion); len(errs) > 0 { return nil, kerrors.NewInvalid("minion", minion.Name, errs) } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion/rest_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion/rest_test.go index 8793ff595bd7..a18eade0518b 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion/rest_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion/rest_test.go @@ -18,13 +18,11 @@ package minion import ( "testing" - "time" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" - "github.com/GoogleCloudPlatform/kubernetes/pkg/util" ) func TestMinionRegistryREST(t *testing.T) { @@ -42,7 +40,7 @@ func TestMinionRegistryREST(t *testing.T) { c, err := ms.Create(ctx, &api.Node{ObjectMeta: api.ObjectMeta{Name: "baz"}}) if err != nil { - t.Errorf("insert failed") + t.Fatalf("insert failed: %v", err) } obj := <-c if !api.HasObjectMetaSystemFieldValues(&obj.Object.(*api.Node).ObjectMeta) { @@ -57,7 +55,7 @@ func TestMinionRegistryREST(t *testing.T) { c, err = ms.Delete(ctx, "bar") if err != nil { - t.Errorf("delete failed") + t.Fatalf("delete failed") } obj = <-c if s, ok := obj.Object.(*api.Status); !ok || s.Status != api.StatusSuccess { @@ -69,7 +67,7 @@ func TestMinionRegistryREST(t *testing.T) { _, err = ms.Delete(ctx, "bar") if err != ErrDoesNotExist { - t.Errorf("delete returned wrong error") + t.Fatalf("delete returned wrong error") } list, err := ms.List(ctx, labels.Everything(), labels.Everything()) @@ -89,57 +87,6 @@ func TestMinionRegistryREST(t *testing.T) { } } -func TestMinionRegistryHealthCheck(t *testing.T) { - minionRegistry := registrytest.NewMinionRegistry([]string{}, api.NodeResources{}) - minionHealthRegistry := NewHealthyRegistry( - minionRegistry, - ¬Minion{minion: "m1"}, - &util.FakeClock{}, - 60*time.Second, - ) - - ms := NewREST(minionHealthRegistry) - ctx := api.NewContext() - - c, err := ms.Create(ctx, &api.Node{ObjectMeta: api.ObjectMeta{Name: "m1"}}) - if err != nil { - t.Errorf("insert failed") - } - result := <-c - if m, ok := result.Object.(*api.Node); !ok || m.Name != "m1" { - t.Errorf("insert return value was weird: %#v", result) - } - if _, err := ms.Get(ctx, "m1"); err != nil { - t.Errorf("node is unhealthy, expect no error: %v", err) - } -} - -func contains(nodes *api.NodeList, nodeID string) bool { - for _, node := range nodes.Items { - if node.Name == nodeID { - return true - } - } - return false -} - -func TestMinionRegistryInvalidUpdate(t *testing.T) { - storage := NewREST(registrytest.NewMinionRegistry([]string{"foo", "bar"}, api.NodeResources{})) - ctx := api.NewContext() - obj, err := storage.Get(ctx, "foo") - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - minion, ok := obj.(*api.Node) - if !ok { - t.Fatalf("Object is not a minion: %#v", obj) - } - minion.Status.HostIP = "1.2.3.4" - if _, err = storage.Update(ctx, minion); err == nil { - t.Error("Unexpected non-error.") - } -} - func TestMinionRegistryValidUpdate(t *testing.T) { storage := NewREST(registrytest.NewMinionRegistry([]string{"foo", "bar"}, api.NodeResources{})) ctx := api.NewContext() @@ -192,3 +139,12 @@ func TestMinionRegistryValidatesCreate(t *testing.T) { } } } + +func contains(nodes *api.NodeList, nodeID string) bool { + for _, node := range nodes.Items { + if node.Name == nodeID { + return true + } + } + return false +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod/rest.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod/rest.go index d6a3f47145ef..2693865bbefc 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod/rest.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod/rest.go @@ -32,6 +32,7 @@ import ( type PodStatusGetter interface { GetPodStatus(namespace, name string) (*api.PodStatus, error) + ClearPodStatus(namespace, name string) } // REST implements the RESTStorage interface in terms of a PodRegistry. @@ -77,6 +78,12 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE func (rs *REST) Delete(ctx api.Context, id string) (<-chan apiserver.RESTResult, error) { return apiserver.MakeAsync(func() (runtime.Object, error) { + namespace, found := api.NamespaceFrom(ctx) + if !found { + return &api.Status{Status: api.StatusFailure}, nil + } + rs.podCache.ClearPodStatus(namespace, id) + return &api.Status{Status: api.StatusSuccess}, rs.registry.DeletePod(ctx, id) }), nil } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod/rest_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod/rest_test.go index 0b63cf726b6d..50e0ccd3049c 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod/rest_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod/rest_test.go @@ -36,6 +36,8 @@ import ( type fakeCache struct { requestedNamespace string requestedName string + clearedNamespace string + clearedName string statusToReturn *api.PodStatus errorToReturn error @@ -47,6 +49,11 @@ func (f *fakeCache) GetPodStatus(namespace, name string) (*api.PodStatus, error) return f.statusToReturn, f.errorToReturn } +func (f *fakeCache) ClearPodStatus(namespace, name string) { + f.clearedNamespace = namespace + f.clearedName = name +} + func expectApiStatusError(t *testing.T, ch <-chan apiserver.RESTResult, msg string) { out := <-ch status, ok := out.Object.(*api.Status) @@ -583,3 +590,31 @@ func TestResourceLocation(t *testing.T) { } } } + +func TestDeletePod(t *testing.T) { + podRegistry := registrytest.NewPodRegistry(nil) + podRegistry.Pod = &api.Pod{ + ObjectMeta: api.ObjectMeta{Name: "foo"}, + Status: api.PodStatus{Host: "machine"}, + } + fakeCache := &fakeCache{} + storage := REST{ + registry: podRegistry, + podCache: fakeCache, + } + ctx := api.NewDefaultContext() + channel, err := storage.Delete(ctx, "foo") + if err != nil { + t.Errorf("unexpected error: %v", err) + } + var result apiserver.RESTResult + select { + case result = <-channel: + // Do nothing, this is expected. + case <-time.After(time.Millisecond * 100): + t.Error("Unexpected timeout on async channel") + } + if fakeCache.clearedNamespace != "default" || fakeCache.clearedName != "foo" { + t.Errorf("Unexpeceted cache delete: %s %s %#v", fakeCache.clearedName, fakeCache.clearedNamespace, result.Object) + } +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/doc.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/doc.go new file mode 100644 index 000000000000..4d6a1de1959b --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 resourcequota provides Registry interface and it's REST +// implementation for storing ResourceQuota api objects. +package resourcequota diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/registry.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/registry.go new file mode 100644 index 000000000000..2a918e96d5f1 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/registry.go @@ -0,0 +1,75 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 resourcequota + +import ( + "fmt" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" + etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" + "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequotausage" + "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" +) + +// Registry implements operations to modify ResourceQuota objects +type Registry interface { + generic.Registry + resourcequotausage.Registry +} + +// registry implements custom changes to generic.Etcd. +type registry struct { + *etcdgeneric.Etcd +} + +// ApplyStatus atomically updates the ResourceQuotaStatus based on the observed ResourceQuotaUsage +func (r *registry) ApplyStatus(ctx api.Context, usage *api.ResourceQuotaUsage) error { + obj, err := r.Get(ctx, usage.Name) + if err != nil { + return err + } + + if len(usage.ResourceVersion) == 0 { + return fmt.Errorf("A resource observation must have a resourceVersion specified to ensure atomic updates") + } + + // set the status + resourceQuota := obj.(*api.ResourceQuota) + resourceQuota.ResourceVersion = usage.ResourceVersion + resourceQuota.Status = usage.Status + return r.Update(ctx, resourceQuota.Name, resourceQuota) +} + +// NewEtcdRegistry returns a registry which will store ResourceQuota in the given helper +func NewEtcdRegistry(h tools.EtcdHelper) Registry { + return ®istry{ + Etcd: &etcdgeneric.Etcd{ + NewFunc: func() runtime.Object { return &api.ResourceQuota{} }, + NewListFunc: func() runtime.Object { return &api.ResourceQuotaList{} }, + EndpointName: "resourcequotas", + KeyRootFunc: func(ctx api.Context) string { + return etcdgeneric.NamespaceKeyRootFunc(ctx, "/registry/resourcequotas") + }, + KeyFunc: func(ctx api.Context, id string) (string, error) { + return etcdgeneric.NamespaceKeyFunc(ctx, "/registry/resourcequotas", id) + }, + Helper: h, + }, + } +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/registry_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/registry_test.go new file mode 100644 index 000000000000..573ebf2e9b10 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/registry_test.go @@ -0,0 +1,116 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 resourcequota + +import ( + "reflect" + "testing" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" + "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" + etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" + "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" + + "github.com/coreos/go-etcd/etcd" +) + +func NewTestLimitRangeEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, generic.Registry) { + f := tools.NewFakeEtcdClient(t) + f.TestIndex = true + h := tools.EtcdHelper{f, testapi.Codec(), tools.RuntimeVersionAdapter{testapi.MetadataAccessor()}} + return f, NewEtcdRegistry(h) +} + +func TestResourceQuotaCreate(t *testing.T) { + resourceQuota := &api.ResourceQuota{ + ObjectMeta: api.ObjectMeta{ + Name: "abc", + Namespace: "default", + }, + Spec: api.ResourceQuotaSpec{ + Hard: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100"), + api.ResourceMemory: resource.MustParse("10000"), + api.ResourcePods: resource.MustParse("10"), + api.ResourceServices: resource.MustParse("10"), + api.ResourceReplicationControllers: resource.MustParse("10"), + api.ResourceQuotas: resource.MustParse("10"), + }, + }, + } + + nodeWithResourceQuota := tools.EtcdResponseWithError{ + R: &etcd.Response{ + Node: &etcd.Node{ + Value: runtime.EncodeOrDie(testapi.Codec(), resourceQuota), + ModifiedIndex: 1, + CreatedIndex: 1, + }, + }, + E: nil, + } + + emptyNode := tools.EtcdResponseWithError{ + R: &etcd.Response{}, + E: tools.EtcdErrorNotFound, + } + + ctx := api.NewDefaultContext() + key := "abc" + path, err := etcdgeneric.NamespaceKeyFunc(ctx, "/registry/resourcequotas", key) + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + + table := map[string]struct { + existing tools.EtcdResponseWithError + expect tools.EtcdResponseWithError + toCreate runtime.Object + errOK func(error) bool + }{ + "normal": { + existing: emptyNode, + expect: nodeWithResourceQuota, + toCreate: resourceQuota, + errOK: func(err error) bool { return err == nil }, + }, + "preExisting": { + existing: nodeWithResourceQuota, + expect: nodeWithResourceQuota, + toCreate: resourceQuota, + errOK: errors.IsAlreadyExists, + }, + } + + for name, item := range table { + fakeClient, registry := NewTestLimitRangeEtcdRegistry(t) + fakeClient.Data[path] = item.existing + err := registry.Create(ctx, key, item.toCreate) + if !item.errOK(err) { + t.Errorf("%v: unexpected error: %v, %v", name, err, path) + } + + if e, a := item.expect, fakeClient.Data[path]; !reflect.DeepEqual(e, a) { + t.Errorf("%v:\n%s", name, util.ObjectDiff(e, a)) + } + } +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/rest.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/rest.go new file mode 100644 index 000000000000..3f22be18826e --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/rest.go @@ -0,0 +1,162 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 resourcequota + +import ( + "fmt" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation" + "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" + "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" + "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" + "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" + "github.com/GoogleCloudPlatform/kubernetes/pkg/watch" +) + +// REST provides the RESTStorage access patterns to work with ResourceQuota objects. +type REST struct { + registry generic.Registry +} + +// NewREST returns a new REST. You must use a registry created by +// NewEtcdRegistry unless you're testing. +func NewREST(registry generic.Registry) *REST { + return &REST{ + registry: registry, + } +} + +// Create a ResourceQuota object +func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RESTResult, error) { + resourceQuota, ok := obj.(*api.ResourceQuota) + if !ok { + return nil, fmt.Errorf("invalid object type") + } + + if !api.ValidNamespace(ctx, &resourceQuota.ObjectMeta) { + return nil, errors.NewConflict("resourceQuota", resourceQuota.Namespace, fmt.Errorf("ResourceQuota.Namespace does not match the provided context")) + } + + if len(resourceQuota.Name) == 0 { + resourceQuota.Name = string(util.NewUUID()) + } + + // callers are not able to set status, instead, it is supplied via a control loop + resourceQuota.Status = api.ResourceQuotaStatus{} + + if errs := validation.ValidateResourceQuota(resourceQuota); len(errs) > 0 { + return nil, errors.NewInvalid("resourceQuota", resourceQuota.Name, errs) + } + api.FillObjectMetaSystemFields(ctx, &resourceQuota.ObjectMeta) + + return apiserver.MakeAsync(func() (runtime.Object, error) { + err := rs.registry.Create(ctx, resourceQuota.Name, resourceQuota) + if err != nil { + return nil, err + } + return rs.registry.Get(ctx, resourceQuota.Name) + }), nil +} + +// Update updates a ResourceQuota object. +func (rs *REST) Update(ctx api.Context, obj runtime.Object) (<-chan apiserver.RESTResult, error) { + resourceQuota, ok := obj.(*api.ResourceQuota) + if !ok { + return nil, fmt.Errorf("invalid object type") + } + + if !api.ValidNamespace(ctx, &resourceQuota.ObjectMeta) { + return nil, errors.NewConflict("resourceQuota", resourceQuota.Namespace, fmt.Errorf("ResourceQuota.Namespace does not match the provided context")) + } + + oldObj, err := rs.registry.Get(ctx, resourceQuota.Name) + if err != nil { + return nil, err + } + + editResourceQuota := oldObj.(*api.ResourceQuota) + + // set the editable fields on the existing object + editResourceQuota.Labels = resourceQuota.Labels + editResourceQuota.ResourceVersion = resourceQuota.ResourceVersion + editResourceQuota.Annotations = resourceQuota.Annotations + editResourceQuota.Spec = resourceQuota.Spec + + if errs := validation.ValidateResourceQuota(editResourceQuota); len(errs) > 0 { + return nil, errors.NewInvalid("resourceQuota", editResourceQuota.Name, errs) + } + + return apiserver.MakeAsync(func() (runtime.Object, error) { + err := rs.registry.Update(ctx, editResourceQuota.Name, editResourceQuota) + if err != nil { + return nil, err + } + return rs.registry.Get(ctx, editResourceQuota.Name) + }), nil +} + +// Delete deletes the ResourceQuota with the specified name +func (rs *REST) Delete(ctx api.Context, name string) (<-chan apiserver.RESTResult, error) { + obj, err := rs.registry.Get(ctx, name) + if err != nil { + return nil, err + } + _, ok := obj.(*api.ResourceQuota) + if !ok { + return nil, fmt.Errorf("invalid object type") + } + return apiserver.MakeAsync(func() (runtime.Object, error) { + return &api.Status{Status: api.StatusSuccess}, rs.registry.Delete(ctx, name) + }), nil +} + +// Get gets a ResourceQuota with the specified name +func (rs *REST) Get(ctx api.Context, name string) (runtime.Object, error) { + obj, err := rs.registry.Get(ctx, name) + if err != nil { + return nil, err + } + resourceQuota, ok := obj.(*api.ResourceQuota) + if !ok { + return nil, fmt.Errorf("invalid object type") + } + return resourceQuota, err +} + +func (rs *REST) getAttrs(obj runtime.Object) (objLabels, objFields labels.Set, err error) { + return labels.Set{}, labels.Set{}, nil +} + +func (rs *REST) List(ctx api.Context, label, field labels.Selector) (runtime.Object, error) { + return rs.registry.List(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs}) +} + +func (rs *REST) Watch(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { + return rs.registry.Watch(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs}, resourceVersion) +} + +// New returns a new api.ResourceQuota +func (*REST) New() runtime.Object { + return &api.ResourceQuota{} +} + +func (*REST) NewList() runtime.Object { + return &api.ResourceQuotaList{} +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/rest_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/rest_test.go new file mode 100644 index 000000000000..45930005154d --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/rest_test.go @@ -0,0 +1,17 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 resourcequota diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequotausage/doc.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequotausage/doc.go new file mode 100644 index 000000000000..9892fc3cba1e --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequotausage/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 resourcequotausage provides Registry interface and it's REST +// implementation for storing ResourceQuotaUsage api objects. +package resourcequotausage diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequotausage/registry.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequotausage/registry.go new file mode 100644 index 000000000000..021006727235 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequotausage/registry.go @@ -0,0 +1,28 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 resourcequotausage + +import ( + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" +) + +// Registry contains the functions needed to support a ResourceQuotaUsage +type Registry interface { + // ApplyStatus should update the ResourceQuota.Status with latest observed state. + // This should be atomic, and idempotent based on the ResourceVersion + ApplyStatus(ctx api.Context, usage *api.ResourceQuotaUsage) error +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequotausage/rest.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequotausage/rest.go new file mode 100644 index 000000000000..cfd63cf4c7a7 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequotausage/rest.go @@ -0,0 +1,56 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 resourcequotausage + +import ( + "fmt" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" + "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" +) + +// REST implements the RESTStorage interface for ResourceQuotaUsage +type REST struct { + registry Registry +} + +// NewREST creates a new REST backed by the given registry. +func NewREST(registry Registry) *REST { + return &REST{ + registry: registry, + } +} + +// New returns a new resource observation object +func (*REST) New() runtime.Object { + return &api.ResourceQuotaUsage{} +} + +// Create takes the incoming ResourceQuotaUsage and applies the latest status atomically to a ResourceQuota +func (b *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RESTResult, error) { + resourceQuotaUsage, ok := obj.(*api.ResourceQuotaUsage) + if !ok { + return nil, fmt.Errorf("incorrect type: %#v", obj) + } + return apiserver.MakeAsync(func() (runtime.Object, error) { + if err := b.registry.ApplyStatus(ctx, resourceQuotaUsage); err != nil { + return nil, err + } + return &api.Status{Status: api.StatusSuccess}, nil + }), nil +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequotausage/rest_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequotausage/rest_test.go new file mode 100644 index 000000000000..1298a9c0de15 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequotausage/rest_test.go @@ -0,0 +1,17 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 resourcequotausage diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/rest.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/rest.go index b62e8c03edc8..718b34b798e0 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/rest.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/rest.go @@ -84,7 +84,7 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE if !api.ValidNamespace(ctx, &service.ObjectMeta) { return nil, errors.NewConflict("service", service.Namespace, fmt.Errorf("Service.Namespace does not match the provided context")) } - if errs := validation.ValidateService(service, rs.registry, ctx); len(errs) > 0 { + if errs := validation.ValidateService(service); len(errs) > 0 { return nil, errors.NewInvalid("service", service.Name, errs) } @@ -226,20 +226,21 @@ func (rs *REST) Update(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE if !api.ValidNamespace(ctx, &service.ObjectMeta) { return nil, errors.NewConflict("service", service.Namespace, fmt.Errorf("Service.Namespace does not match the provided context")) } - if errs := validation.ValidateService(service, rs.registry, ctx); len(errs) > 0 { + + oldService, err := rs.registry.GetService(ctx, service.Name) + if err != nil { + return nil, err + } + + // Copy over non-user fields + // TODO: this should be a Status field, since the end user does not set it. + // TODO: make this a merge function + service.Spec.ProxyPort = oldService.Spec.ProxyPort + + if errs := validation.ValidateServiceUpdate(oldService, service); len(errs) > 0 { return nil, errors.NewInvalid("service", service.Name, errs) } return apiserver.MakeAsync(func() (runtime.Object, error) { - cur, err := rs.registry.GetService(ctx, service.Name) - if err != nil { - return nil, err - } - if service.Spec.PortalIP != "" && service.Spec.PortalIP != cur.Spec.PortalIP { - el := errors.ValidationErrorList{errors.NewFieldInvalid("spec.portalIP", service.Spec.PortalIP, "field is immutable")} - return nil, errors.NewInvalid("service", service.Name, el) - } - // Copy over non-user fields. - service.Spec.ProxyPort = cur.Spec.ProxyPort // TODO: check to see if external load balancer status changed err = rs.registry.UpdateService(ctx, service) if err != nil { diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/rest_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/rest_test.go index ab288b0ae91a..eec35f117be7 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/rest_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service/rest_test.go @@ -118,7 +118,7 @@ func TestServiceRegistryUpdate(t *testing.T) { ctx := api.NewDefaultContext() registry := registrytest.NewServiceRegistry() registry.CreateService(ctx, &api.Service{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, + ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: api.NamespaceDefault}, Spec: api.ServiceSpec{ Port: 6502, Selector: map[string]string{"bar": "baz1"}, @@ -132,12 +132,12 @@ func TestServiceRegistryUpdate(t *testing.T) { Selector: map[string]string{"bar": "baz2"}, }, }) + if err != nil { + t.Fatalf("Expected no error: %v", err) + } if c == nil { t.Errorf("Expected non-nil channel") } - if err != nil { - t.Errorf("Expected no error") - } updated_svc := <-c updated_service := updated_svc.Object.(*api.Service) if updated_service.Name != "foo" { @@ -531,11 +531,9 @@ func TestServiceRegistryIPUpdate(t *testing.T) { update.Spec.Port = 6503 update.Spec.PortalIP = "1.2.3.76" // error - c, _ = rest.Update(ctx, update) - result := <-c - st := result.Object.(*api.Status) - if st.Reason != api.StatusReasonInvalid { - t.Errorf("Expected to get an invalid error, got %v", st) + _, err := rest.Update(ctx, update) + if err == nil || !errors.IsInvalid(err) { + t.Error("Unexpected error type: %v", err) } } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/runtime/types.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/runtime/types.go index da7e0e93c5d8..fec130302061 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/runtime/types.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/runtime/types.go @@ -16,8 +16,6 @@ limitations under the License. package runtime -import () - // Note that the types provided in this file are not versioned and are intended to be // safe to use from within all versions of every API object. diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcd_tools.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcd_tools.go index 8e332a9c5359..430f50ae8bb3 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcd_tools.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcd_tools.go @@ -147,7 +147,7 @@ func etcdErrorIndex(err error) (uint64, bool) { } func (h *EtcdHelper) listEtcdNode(key string) ([]*etcd.Node, uint64, error) { - result, err := h.Client.Get(key, false, true) + result, err := h.Client.Get(key, true, true) if err != nil { index, ok := etcdErrorIndex(err) if !ok { diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcd_tools_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcd_tools_test.go index 6a9e7fa04822..e151f002ddc2 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcd_tools_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/tools/etcd_tools_test.go @@ -30,11 +30,6 @@ import ( "github.com/coreos/go-etcd/etcd" ) -type fakeClientGetSet struct { - get func(key string, sort, recursive bool) (*etcd.Response, error) - set func(key, value string, ttl uint64) (*etcd.Response, error) -} - type TestResource struct { api.TypeMeta `json:",inline"` api.ObjectMeta `json:"metadata"` @@ -72,17 +67,24 @@ func TestExtractToList(t *testing.T) { R: &etcd.Response{ EtcdIndex: 10, Node: &etcd.Node{ + Dir: true, Nodes: []*etcd.Node{ { + Key: "/foo", Value: `{"id":"foo","kind":"Pod","apiVersion":"v1beta1"}`, + Dir: false, ModifiedIndex: 1, }, { + Key: "/bar", Value: `{"id":"bar","kind":"Pod","apiVersion":"v1beta1"}`, + Dir: false, ModifiedIndex: 2, }, { + Key: "/baz", Value: `{"id":"baz","kind":"Pod","apiVersion":"v1beta1"}`, + Dir: false, ModifiedIndex: 3, }, }, @@ -92,9 +94,10 @@ func TestExtractToList(t *testing.T) { expect := api.PodList{ ListMeta: api.ListMeta{ResourceVersion: "10"}, Items: []api.Pod{ - {ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}}, + // We expect items to be sorted by its name. {ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "2"}}, {ObjectMeta: api.ObjectMeta{Name: "baz", ResourceVersion: "3"}}, + {ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}}, }, } @@ -116,22 +119,34 @@ func TestExtractToListAcrossDirectories(t *testing.T) { R: &etcd.Response{ EtcdIndex: 10, Node: &etcd.Node{ + Dir: true, Nodes: []*etcd.Node{ { + Key: "/directory1", Value: `{"name": "directory1"}`, Dir: true, Nodes: []*etcd.Node{ { + Key: "/foo", Value: `{"id":"foo","kind":"Pod","apiVersion":"v1beta1"}`, + Dir: false, + ModifiedIndex: 1, + }, + { + Key: "/baz", + Value: `{"id":"baz","kind":"Pod","apiVersion":"v1beta1"}`, + Dir: false, ModifiedIndex: 1, }, }, }, { + Key: "/directory2", Value: `{"name": "directory2"}`, Dir: true, Nodes: []*etcd.Node{ { + Key: "/bar", Value: `{"id":"bar","kind":"Pod","apiVersion":"v1beta1"}`, ModifiedIndex: 2, }, @@ -144,6 +159,8 @@ func TestExtractToListAcrossDirectories(t *testing.T) { expect := api.PodList{ ListMeta: api.ListMeta{ResourceVersion: "10"}, Items: []api.Pod{ + // We expect list to be sorted by directory (e.g. namespace) first, then by name. + {ObjectMeta: api.ObjectMeta{Name: "baz", ResourceVersion: "1"}}, {ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}}, {ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "2"}}, }, @@ -166,20 +183,25 @@ func TestExtractToListExcludesDirectories(t *testing.T) { R: &etcd.Response{ EtcdIndex: 10, Node: &etcd.Node{ + Dir: true, Nodes: []*etcd.Node{ { + Key: "/foo", Value: `{"id":"foo","kind":"Pod","apiVersion":"v1beta1"}`, ModifiedIndex: 1, }, { + Key: "/bar", Value: `{"id":"bar","kind":"Pod","apiVersion":"v1beta1"}`, ModifiedIndex: 2, }, { + Key: "/baz", Value: `{"id":"baz","kind":"Pod","apiVersion":"v1beta1"}`, ModifiedIndex: 3, }, { + Key: "/directory", Value: `{"name": "directory"}`, Dir: true, }, @@ -190,9 +212,9 @@ func TestExtractToListExcludesDirectories(t *testing.T) { expect := api.PodList{ ListMeta: api.ListMeta{ResourceVersion: "10"}, Items: []api.Pod{ - {ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}}, {ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "2"}}, {ObjectMeta: api.ObjectMeta{Name: "baz", ResourceVersion: "3"}}, + {ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}}, }, } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/tools/fake_etcd_client.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/tools/fake_etcd_client.go index 1d8821e46436..5250187cc973 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/tools/fake_etcd_client.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/tools/fake_etcd_client.go @@ -19,6 +19,7 @@ package tools import ( "errors" "fmt" + "sort" "sync" "github.com/coreos/go-etcd/etcd" @@ -132,9 +133,23 @@ func (f *FakeEtcdClient) Get(key string, sort, recursive bool) (*etcd.Response, return &etcd.Response{}, EtcdErrorNotFound } f.t.Logf("returning %v: %#v %#v", key, result.R, result.E) + + // Sort response, note this will alter resutl.R. + if result.R.Node != nil && result.R.Node.Nodes != nil && sort { + f.sortResponse(result.R.Node.Nodes) + } return result.R, result.E } +func (f *FakeEtcdClient) sortResponse(nodes etcd.Nodes) { + for i := range nodes { + if nodes[i].Dir { + f.sortResponse(nodes[i].Nodes) + } + } + sort.Sort(nodes) +} + func (f *FakeEtcdClient) nodeExists(key string) bool { result, ok := f.Data[key] return ok && result.R != nil && result.R.Node != nil && result.E == nil diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/bool_flag.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/bool_flag.go new file mode 100644 index 000000000000..fef6b3f7fd8b --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/bool_flag.go @@ -0,0 +1,64 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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" + "strconv" +) + +// BoolFlag is a boolean flag compatible with flags and pflags that keeps track of whether it had a value supplied or not. +// Beware! If you use this type, you must actually specify --flag-name=true, you cannot leave it as --flag-name and still have +// the value set +type BoolFlag struct { + // If Set has been invoked this value is true + provided bool + // The exact value provided on the flag + value bool +} + +func (f *BoolFlag) Default(value bool) { + f.value = value +} + +func (f BoolFlag) String() string { + return fmt.Sprintf("%t", f.value) +} + +func (f BoolFlag) Value() bool { + return f.value +} + +func (f *BoolFlag) Set(value string) error { + boolVal, err := strconv.ParseBool(value) + if err != nil { + return err + } + + f.value = boolVal + f.provided = true + + return nil +} + +func (f BoolFlag) Provided() bool { + return f.provided +} + +func (f *BoolFlag) Type() string { + return "bool" +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/pflag_import.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/pflag_import.go index e45d88ef23c2..fcef3175de02 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/pflag_import.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/pflag_import.go @@ -80,7 +80,9 @@ func (v *flagValueWrapper) IsBoolFlag() bool { // Imports a 'flag.Flag' into a 'pflag.FlagSet'. The "short" option is unset // and the type is inferred using reflection. func AddFlagToPFlagSet(f *flag.Flag, fs *pflag.FlagSet) { - fs.Var(wrapFlagValue(f.Value), f.Name, f.Usage) + if fs.Lookup(f.Name) == nil { + fs.Var(wrapFlagValue(f.Value), f.Name, f.Usage) + } } // Adds all of the flags in a 'flag.FlagSet' package flags to a 'pflag.FlagSet'. diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/slice/slice.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/slice/slice.go new file mode 100644 index 000000000000..d6f5eb74e42f --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/slice/slice.go @@ -0,0 +1,49 @@ +/* +Copyright 2015 Google Inc. All rights reserved. + +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 slice provides utility methods for common operations on slices. +package slice + +import ( + "math/rand" + "sort" +) + +// CopyStrings copies the contents of the specified string slice +// into a new slice. +func CopyStrings(s []string) []string { + c := make([]string, len(s)) + copy(c, s) + return c +} + +// SortStrings sorts the specified string slice in place. It returns the same +// slice that was provided in order to facilitate method chaining. +func SortStrings(s []string) []string { + sort.Strings(s) + return s +} + +// ShuffleStrings copies strings from the specified slice into a copy in random +// order. It returns a new slice. +func ShuffleStrings(s []string) []string { + shuffled := make([]string, len(s)) + perm := rand.Perm(len(s)) + for i, j := range perm { + shuffled[j] = s[i] + } + return shuffled +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/slice/slice_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/slice/slice_test.go new file mode 100644 index 000000000000..a0a61a5b1d43 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/slice/slice_test.go @@ -0,0 +1,70 @@ +/* +Copyright 2015 Google Inc. All rights reserved. + +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 slice + +import ( + "reflect" + "testing" +) + +func TestCopyStrings(t *testing.T) { + src := []string{"a", "c", "b"} + dest := CopyStrings(src) + + if !reflect.DeepEqual(src, dest) { + t.Errorf("%v and %v are not equal", src, dest) + } + + src[0] = "A" + if reflect.DeepEqual(src, dest) { + t.Errorf("CopyStrings didn't make a copy") + } +} + +func TestSortStrings(t *testing.T) { + src := []string{"a", "c", "b"} + dest := SortStrings(src) + expected := []string{"a", "b", "c"} + + if !reflect.DeepEqual(dest, expected) { + t.Errorf("SortString didn't sort the strings") + } + + if !reflect.DeepEqual(src, expected) { + t.Errorf("SortString didn't sort in place") + } +} + +func TestShuffleStrings(t *testing.T) { + src := []string{"a", "b", "c", "d", "e", "f"} + dest := ShuffleStrings(src) + + if len(src) != len(dest) { + t.Errorf("Shuffled slice is wrong length, expected %v got %v", len(src), len(dest)) + } + + m := make(map[string]bool, len(dest)) + for _, s := range dest { + m[s] = true + } + + for _, k := range src { + if _, exists := m[k]; !exists { + t.Errorf("Element %v missing from shuffled slice", k) + } + } +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/string_flag.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/string_flag.go new file mode 100644 index 000000000000..0dbd12495f01 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/string_flag.go @@ -0,0 +1,52 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +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 + +// StringFlag is a string flag compatible with flags and pflags that keeps track of whether it had a value supplied or not. +type StringFlag struct { + // If Set has been invoked this value is true + provided bool + // The exact value provided on the flag + value string +} + +func (f *StringFlag) Default(value string) { + f.value = value +} + +func (f StringFlag) String() string { + return f.value +} + +func (f StringFlag) Value() string { + return f.value +} + +func (f *StringFlag) Set(value string) error { + f.value = value + f.provided = true + + return nil +} + +func (f StringFlag) Provided() bool { + return f.provided +} + +func (f *StringFlag) Type() string { + return "string" +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/template.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/template.go new file mode 100644 index 000000000000..f79b817c479d --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/template.go @@ -0,0 +1,48 @@ +/* +Copyright 2015 Google Inc. All rights reserved. + +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 ( + "bytes" + "go/doc" + "io" + "strings" + "text/template" +) + +func wrap(indent string, s string) string { + var buf bytes.Buffer + doc.ToText(&buf, s, indent, indent+" ", 80-len(indent)) + return buf.String() +} + +// ExecuteTemplate executes templateText with data and output written to w. +func ExecuteTemplate(w io.Writer, templateText string, data interface{}) error { + t := template.New("top") + t.Funcs(template.FuncMap{ + "trim": strings.TrimSpace, + "wrap": wrap, + }) + template.Must(t.Parse(templateText)) + return t.Execute(w, data) +} + +func ExecuteTemplateToString(templateText string, data interface{}) (string, error) { + b := bytes.Buffer{} + err := ExecuteTemplate(&b, templateText, data) + return b.String(), err +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/template_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/template_test.go new file mode 100644 index 000000000000..707ee2f79261 --- /dev/null +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/template_test.go @@ -0,0 +1,61 @@ +/* +Copyright 2015 Google Inc. All rights reserved. + +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 ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestWrap(t *testing.T) { + tt := `before ->{{.Long | wrap "**"}}<- after` + data := struct { + Long string + }{ + `Hodor, hodor; hodor hodor; +hodor hodor... Hodor hodor hodor? Hodor. Hodor hodor hodor hodor... +Hodor hodor hodor; hodor hodor hodor! Hodor, hodor. Hodor. Hodor, +HODOR hodor, hodor hodor; hodor hodor; hodor HODOR hodor, hodor hodor? +Hodor. Hodor hodor - hodor hodor. Hodor hodor HODOR! Hodor hodor - hodor... +Hodor hodor HODOR hodor, hodor hodor hodor! Hodor, hodor... Hodor hodor +hodor hodor hodor hodor! Hodor, hodor; hodor hodor. Hodor.`, + } + output, _ := ExecuteTemplateToString(tt, data) + t.Logf("%q", output) + + assert.Equal(t, `before ->**Hodor, hodor; hodor hodor; hodor hodor... Hodor hodor hodor? Hodor. Hodor +**hodor hodor hodor... Hodor hodor hodor; hodor hodor hodor! Hodor, hodor. +**Hodor. Hodor, HODOR hodor, hodor hodor; hodor hodor; hodor HODOR hodor, hodor +**hodor? Hodor. Hodor hodor - hodor hodor. Hodor hodor HODOR! Hodor hodor - +**hodor... Hodor hodor HODOR hodor, hodor hodor hodor! Hodor, hodor... Hodor +**hodor hodor hodor hodor hodor! Hodor, hodor; hodor hodor. Hodor. +<- after`, output) +} + +func TestTrim(t *testing.T) { + tt := `before ->{{.Messy | trim }}<- after` + data := struct { + Messy string + }{ + "\t stuff\n \r ", + } + output, _ := ExecuteTemplateToString(tt, data) + t.Logf("%q", output) + + assert.Equal(t, `before ->stuff<- after`, output) +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/util.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/util.go index 63f2d670b8a9..d7e6a37dea2b 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/util.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/util.go @@ -20,10 +20,12 @@ import ( "encoding/json" "fmt" "io/ioutil" + "path" "reflect" "regexp" "runtime" "strconv" + "strings" "time" "github.com/golang/glog" @@ -210,3 +212,20 @@ func AllPtrFieldsNil(obj interface{}) bool { } return true } + +// Splits a fully qualified name and returns its namespace and name. +// Assumes that the input 'str' has been validated. +func SplitQualifiedName(str string) (string, string) { + parts := strings.Split(str, "/") + if len(parts) < 2 { + return "", str + } + + return parts[0], parts[1] +} + +// Joins 'namespace' and 'name' and returns a fully qualified name +// Assumes that the input is valid. +func JoinQualifiedName(namespace, name string) string { + return path.Join(namespace, name) +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/util_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/util_test.go index a56c2d49c6c5..57ee2c913841 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/util_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/util/util_test.go @@ -298,3 +298,37 @@ func TestAllPtrFieldsNil(t *testing.T) { } } } + +func TestSplitQualifiedName(t *testing.T) { + testCases := []struct { + input string + output []string + }{ + {"kubernetes.io/blah", []string{"kubernetes.io", "blah"}}, + {"blah", []string{"", "blah"}}, + {"kubernetes.io/blah/blah", []string{"kubernetes.io", "blah"}}, + } + for i, tc := range testCases { + namespace, name := SplitQualifiedName(tc.input) + if namespace != tc.output[0] || name != tc.output[1] { + t.Errorf("case[%d]: expected (%q, %q), got (%q, %q)", i, tc.output[0], tc.output[1], namespace, name) + } + } +} + +func TestJoinQualifiedName(t *testing.T) { + testCases := []struct { + input []string + output string + }{ + {[]string{"kubernetes.io", "blah"}, "kubernetes.io/blah"}, + {[]string{"blah", ""}, "blah"}, + {[]string{"kubernetes.io", "blah"}, "kubernetes.io/blah"}, + } + for i, tc := range testCases { + res := JoinQualifiedName(tc.input[0], tc.input[1]) + if res != tc.output { + t.Errorf("case[%d]: expected %q, got %q", i, tc.output, res) + } + } +} diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/factory/factory.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/factory/factory.go index d8410c4a2f4a..02e3680a2f35 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/factory/factory.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/factory/factory.go @@ -35,9 +35,9 @@ import ( ) var ( - PodLister = &cache.StoreToPodLister{cache.NewStore()} - MinionLister = &cache.StoreToNodeLister{cache.NewStore()} - ServiceLister = &cache.StoreToServiceLister{cache.NewStore()} + PodLister = &cache.StoreToPodLister{cache.NewStore(cache.MetaNamespaceKeyFunc)} + MinionLister = &cache.StoreToNodeLister{cache.NewStore(cache.MetaNamespaceKeyFunc)} + ServiceLister = &cache.StoreToServiceLister{cache.NewStore(cache.MetaNamespaceKeyFunc)} ) // ConfigFactory knows how to fill out a scheduler config with its support functions. @@ -57,7 +57,7 @@ type ConfigFactory struct { func NewConfigFactory(client *client.Client) *ConfigFactory { return &ConfigFactory{ Client: client, - PodQueue: cache.NewFIFO(), + PodQueue: cache.NewFIFO(cache.MetaNamespaceKeyFunc), PodLister: PodLister, MinionLister: MinionLister, ServiceLister: ServiceLister, @@ -205,9 +205,8 @@ func (factory *ConfigFactory) pollMinions() (cache.Enumerator, error) { nodes.Items = append(nodes.Items, node) } } else { - // If no condition is set, either node health check is disabled (master - // flag "healthCheckMinions" is set to false), or we get unknown condition. - // In such cases, we add nodes unconditionally. + // If no condition is set, we get unknown node condition. In such cases, + // we add nodes unconditionally. nodes.Items = append(nodes.Items, node) } } @@ -242,7 +241,7 @@ func (factory *ConfigFactory) makeDefaultErrorFunc(backoff *podBackoff, podQueue return } if pod.Status.Host == "" { - podQueue.Add(pod.Name, pod) + podQueue.Add(pod) } }() } @@ -262,8 +261,8 @@ func (ne *nodeEnumerator) Len() int { } // Get returns the item (and ID) with the particular index. -func (ne *nodeEnumerator) Get(index int) (string, interface{}) { - return ne.Items[index].Name, &ne.Items[index] +func (ne *nodeEnumerator) Get(index int) interface{} { + return &ne.Items[index] } type binder struct { diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/factory/factory_test.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/factory/factory_test.go index 6155b27c882e..4c58bee29145 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/factory/factory_test.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/factory/factory_test.go @@ -208,7 +208,7 @@ func TestDefaultErrorFunc(t *testing.T) { server := httptest.NewServer(mux) defer server.Close() factory := NewConfigFactory(client.NewOrDie(&client.Config{Host: server.URL, Version: testapi.Version()})) - queue := cache.NewFIFO() + queue := cache.NewFIFO(cache.MetaNamespaceKeyFunc) podBackoff := podBackoff{ perPodBackoff: map[string]*backoffEntry{}, clock: &fakeClock{}, @@ -223,7 +223,7 @@ func TestDefaultErrorFunc(t *testing.T) { // whole error handling system in the future. The test will time // out if something doesn't work. time.Sleep(10 * time.Millisecond) - got, exists := queue.Get("foo") + got, exists, _ := queue.Get(testPod) if !exists { continue } @@ -249,8 +249,8 @@ func TestMinionEnumerator(t *testing.T) { t.Fatalf("expected %v, got %v", e, a) } for i := range testList.Items { - gotID, gotObj := me.Get(i) - if e, a := testList.Items[i].Name, gotID; e != a { + gotObj := me.Get(i) + if e, a := testList.Items[i].Name, gotObj.(*api.Node).Name; e != a { t.Errorf("Expected %v, got %v", e, a) } if e, a := &testList.Items[i], gotObj; !reflect.DeepEqual(e, a) { diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/mod/mod.go b/Godeps/_workspace/src/github.com/coreos/etcd/mod/mod.go index c811539cc24d..59358a0c97de 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/mod/mod.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/mod/mod.go @@ -5,7 +5,7 @@ import ( "net/http" "path" - //"github.com/coreos/etcd/mod/dashboard" + "github.com/coreos/etcd/mod/dashboard" leader2 "github.com/coreos/etcd/mod/leader/v2" lock2 "github.com/coreos/etcd/mod/lock/v2" "github.com/coreos/etcd/third_party/github.com/gorilla/mux" @@ -20,10 +20,10 @@ func addSlash(w http.ResponseWriter, req *http.Request) { func HttpHandler(addr string) http.Handler { r := mux.NewRouter() - //r.HandleFunc("/dashboard", addSlash) + r.HandleFunc("/dashboard", addSlash) - //r.PathPrefix("/dashboard/static/").Handler(http.StripPrefix("/dashboard/static/", dashboard.HttpHandler())) - //r.HandleFunc("/dashboard{path:.*}", dashboard.IndexPage) + r.PathPrefix("/dashboard/static/").Handler(http.StripPrefix("/dashboard/static/", dashboard.HttpHandler())) + r.HandleFunc("/dashboard{path:.*}", dashboard.IndexPage) r.PathPrefix("/v2/lock").Handler(http.StripPrefix("/v2/lock", lock2.NewHandler(addr))) r.PathPrefix("/v2/leader").Handler(http.StripPrefix("/v2/leader", leader2.NewHandler(addr))) diff --git a/Godeps/_workspace/src/github.com/getsentry/raven-go/client.go b/Godeps/_workspace/src/github.com/getsentry/raven-go/client.go index 3a9d0e2d663b..ddef470a2336 100644 --- a/Godeps/_workspace/src/github.com/getsentry/raven-go/client.go +++ b/Godeps/_workspace/src/github.com/getsentry/raven-go/client.go @@ -136,7 +136,6 @@ type Packet struct { Logger string `json:"logger"` // Optional - Release string `json:"release,omitempty"` Platform string `json:"platform,omitempty"` Culprit string `json:"culprit,omitempty"` Tags Tags `json:"tags,omitempty"` @@ -267,7 +266,6 @@ type Client struct { mu sync.RWMutex url string projectID string - release string authHeader string queue chan *outgoingPacket } @@ -312,12 +310,6 @@ func (client *Client) SetDSN(dsn string) error { return nil } -func (client *Client) SetRelease(release string) { - client.mu.Lock() - defer client.mu.Unlock() - client.release = release -} - func (client *Client) worker() { for outgoingPacket := range client.queue { client.mu.RLock() @@ -345,7 +337,6 @@ func (client *Client) Capture(packet *Packet, captureTags map[string]string) (ev // Initialize any required packet fields client.mu.RLock() projectID := client.projectID - release := client.release client.mu.RUnlock() err := packet.Init(projectID) @@ -353,7 +344,6 @@ func (client *Client) Capture(packet *Packet, captureTags map[string]string) (ev ch <- err return } - packet.Release = release outgoingPacket := &outgoingPacket{packet, ch} @@ -430,13 +420,6 @@ func (client *Client) ProjectID() string { return client.projectID } -func (client *Client) Release() string { - client.mu.RLock() - defer client.mu.RUnlock() - - return client.release -} - func (client *Client) URL() string { client.mu.RLock() defer client.mu.RUnlock() From 361a1784e6ff49f28e75e20396c6768c05ccaef7 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Tue, 23 Dec 2014 23:26:58 -0500 Subject: [PATCH 02/12] UPSTREAM: Disable UIs for Kubernetes and etcd --- .../GoogleCloudPlatform/kubernetes/pkg/master/master.go | 8 ++++---- Godeps/_workspace/src/github.com/coreos/etcd/mod/mod.go | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/master.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/master.go index cc81000fa52e..4973281fd72d 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/master.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/master.go @@ -55,7 +55,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools" - "github.com/GoogleCloudPlatform/kubernetes/pkg/ui" + //"github.com/GoogleCloudPlatform/kubernetes/pkg/ui" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/emicklei/go-restful" @@ -391,9 +391,9 @@ func (m *Master) init(c *Config) { if c.EnableLogsSupport { apiserver.InstallLogsSupport(m.muxHelper) } - if c.EnableUISupport { - ui.InstallSupport(m.muxHelper, m.enableSwaggerSupport) - } + /*if c.EnableUISupport { + ui.InstallSupport(m.mux) + }*/ // TODO: install runtime/pprof handler // See github.com/emicklei/go-restful/blob/master/examples/restful-cpuprofiler-service.go diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/mod/mod.go b/Godeps/_workspace/src/github.com/coreos/etcd/mod/mod.go index 59358a0c97de..c811539cc24d 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/mod/mod.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/mod/mod.go @@ -5,7 +5,7 @@ import ( "net/http" "path" - "github.com/coreos/etcd/mod/dashboard" + //"github.com/coreos/etcd/mod/dashboard" leader2 "github.com/coreos/etcd/mod/leader/v2" lock2 "github.com/coreos/etcd/mod/lock/v2" "github.com/coreos/etcd/third_party/github.com/gorilla/mux" @@ -20,10 +20,10 @@ func addSlash(w http.ResponseWriter, req *http.Request) { func HttpHandler(addr string) http.Handler { r := mux.NewRouter() - r.HandleFunc("/dashboard", addSlash) + //r.HandleFunc("/dashboard", addSlash) - r.PathPrefix("/dashboard/static/").Handler(http.StripPrefix("/dashboard/static/", dashboard.HttpHandler())) - r.HandleFunc("/dashboard{path:.*}", dashboard.IndexPage) + //r.PathPrefix("/dashboard/static/").Handler(http.StripPrefix("/dashboard/static/", dashboard.HttpHandler())) + //r.HandleFunc("/dashboard{path:.*}", dashboard.IndexPage) r.PathPrefix("/v2/lock").Handler(http.StripPrefix("/v2/lock", lock2.NewHandler(addr))) r.PathPrefix("/v2/leader").Handler(http.StripPrefix("/v2/leader", leader2.NewHandler(addr))) From 5133b9d528b346b769761c6058284932d2b925fb Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Mon, 12 Jan 2015 16:42:06 -0500 Subject: [PATCH 03/12] UPSTREAM: Disable auto-pull when tag is "latest" --- .../kubernetes/pkg/kubelet/dockertools/docker.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools/docker.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools/docker.go index bb030743f772..a08658c367c2 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools/docker.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools/docker.go @@ -245,11 +245,7 @@ func (p dockerPuller) IsImagePresent(image string) (bool, error) { // RequireLatestImage returns if the user wants the latest image func RequireLatestImage(name string) bool { - _, tag := parseImageName(name) - - if tag == "latest" { - return true - } + // REVERTED: Change behavior from upstream return false } From c79fb22b55981cd292e2e8d680c69ba3aa442e1d Mon Sep 17 00:00:00 2001 From: fabianofranz Date: Tue, 13 Jan 2015 17:48:04 -0200 Subject: [PATCH 04/12] UPSTREAM: api registration right on mux makes it invisible to container Conflicts: Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/master.go --- .../GoogleCloudPlatform/kubernetes/pkg/master/master.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/master.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/master.go index 4973281fd72d..170b195260ad 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/master.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/master/master.go @@ -384,7 +384,7 @@ func (m *Master) init(c *Config) { // Register root handler. // We do not register this using restful Webservice since we do not want to surface this in api docs. - m.mux.HandleFunc("/", apiserver.IndexHandler(m.handlerContainer, m.muxHelper)) + //m.mux.HandleFunc("/", apiserver.IndexHandler(m.handlerContainer, m.muxHelper)) // TODO: use go-restful apiserver.InstallValidator(m.muxHelper, func() map[string]apiserver.Server { return m.getServersToValidate(c) }) From 195f71bcfa1495bf6d15f0edda32fe37b74db4f8 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Fri, 30 Jan 2015 17:59:16 -0500 Subject: [PATCH 05/12] UPSTREAM: Allow namespace short to be set --- .../kubernetes/pkg/client/clientcmd/overrides.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/overrides.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/overrides.go index f6309c98c5ec..b22e31664b6d 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/overrides.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/clientcmd/overrides.go @@ -51,10 +51,11 @@ type AuthOverrideFlags struct { // ContextOverrideFlags holds the flag names to be used for binding command line flags for Cluster objects type ContextOverrideFlags struct { - ClusterName string - AuthInfoName string - Namespace string - NamespacePath string + ClusterName string + AuthInfoName string + Namespace string + NamespaceShort string + NamespacePath string } // ClusterOverride holds the flag names to be used for binding command line flags for Cluster objects @@ -150,6 +151,6 @@ func BindOverrideFlags(overrides *ConfigOverrides, flags *pflag.FlagSet, flagNam func BindContextFlags(contextInfo *clientcmdapi.Context, flags *pflag.FlagSet, flagNames ContextOverrideFlags) { flags.StringVar(&contextInfo.Cluster, flagNames.ClusterName, "", "The name of the kubeconfig cluster to use") flags.StringVar(&contextInfo.AuthInfo, flagNames.AuthInfoName, "", "The name of the kubeconfig user to use") - flags.StringVar(&contextInfo.Namespace, flagNames.Namespace, "", "If present, the namespace scope for this CLI request.") + flags.StringVarP(&contextInfo.Namespace, flagNames.Namespace, flagNames.NamespaceShort, "", "If present, the namespace scope for this CLI request.") flags.StringVar(&contextInfo.NamespacePath, flagNames.NamespacePath, "", "Path to the namespace info file that holds the namespace context to use for CLI requests.") } From f8d42a959edd7a6f4cf03a207f36eb6430c05366 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Mon, 26 Jan 2015 17:50:38 -0500 Subject: [PATCH 06/12] UPSTREAM: Add 'release' field to raven-go --- .../src/github.com/getsentry/raven-go/client.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Godeps/_workspace/src/github.com/getsentry/raven-go/client.go b/Godeps/_workspace/src/github.com/getsentry/raven-go/client.go index ddef470a2336..3a9d0e2d663b 100644 --- a/Godeps/_workspace/src/github.com/getsentry/raven-go/client.go +++ b/Godeps/_workspace/src/github.com/getsentry/raven-go/client.go @@ -136,6 +136,7 @@ type Packet struct { Logger string `json:"logger"` // Optional + Release string `json:"release,omitempty"` Platform string `json:"platform,omitempty"` Culprit string `json:"culprit,omitempty"` Tags Tags `json:"tags,omitempty"` @@ -266,6 +267,7 @@ type Client struct { mu sync.RWMutex url string projectID string + release string authHeader string queue chan *outgoingPacket } @@ -310,6 +312,12 @@ func (client *Client) SetDSN(dsn string) error { return nil } +func (client *Client) SetRelease(release string) { + client.mu.Lock() + defer client.mu.Unlock() + client.release = release +} + func (client *Client) worker() { for outgoingPacket := range client.queue { client.mu.RLock() @@ -337,6 +345,7 @@ func (client *Client) Capture(packet *Packet, captureTags map[string]string) (ev // Initialize any required packet fields client.mu.RLock() projectID := client.projectID + release := client.release client.mu.RUnlock() err := packet.Init(projectID) @@ -344,6 +353,7 @@ func (client *Client) Capture(packet *Packet, captureTags map[string]string) (ev ch <- err return } + packet.Release = release outgoingPacket := &outgoingPacket{packet, ch} @@ -420,6 +430,13 @@ func (client *Client) ProjectID() string { return client.projectID } +func (client *Client) Release() string { + client.mu.RLock() + defer client.mu.RUnlock() + + return client.release +} + func (client *Client) URL() string { client.mu.RLock() defer client.mu.RUnlock() From 9aedd3465fc8682dd358f84390608778416ee2b4 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Sat, 31 Jan 2015 22:46:15 -0500 Subject: [PATCH 07/12] UPSTREAM: Support GetByKey so EventStore can de-dup --- .../kubernetes/pkg/client/cache/fifo.go | 9 +++++++-- .../kubernetes/pkg/client/cache/store.go | 14 ++++++++++++-- .../kubernetes/pkg/client/cache/undelta_store.go | 3 +++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/fifo.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/fifo.go index a27028f74262..42c0c42f76b9 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/fifo.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/fifo.go @@ -86,13 +86,18 @@ func (f *FIFO) List() []interface{} { // Get returns the requested item, or sets exists=false. func (f *FIFO) Get(obj interface{}) (item interface{}, exists bool, err error) { - id, err := f.keyFunc(obj) + key, err := f.keyFunc(obj) if err != nil { return nil, false, fmt.Errorf("couldn't create key for object: %v", err) } + return f.GetByKey(key) +} + +// GetByKey returns the requested item, or sets exists=false. +func (f *FIFO) GetByKey(key string) (item interface{}, exists bool, err error) { f.lock.RLock() defer f.lock.RUnlock() - item, exists = f.items[id] + item, exists = f.items[key] return item, exists, nil } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/store.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/store.go index acea6764a2c0..6f953c133e44 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/store.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/store.go @@ -37,6 +37,7 @@ type Store interface { Delete(obj interface{}) error List() []interface{} Get(obj interface{}) (item interface{}, exists bool, err error) + GetByKey(key string) (item interface{}, exists bool, err error) // Replace will delete the contents of the store, using instead the // given list. Store takes ownership of the list, you should not reference @@ -51,6 +52,9 @@ type KeyFunc func(obj interface{}) (string, error) // keys for API objects which implement meta.Interface. // The key uses the format: / func MetaNamespaceKeyFunc(obj interface{}) (string, error) { + if _, ok := obj.(string); ok { + panic("you probably didn't mean to give a string to this function") + } meta, err := meta.Accessor(obj) if err != nil { return "", fmt.Errorf("object has no meta: %v", err) @@ -117,13 +121,19 @@ func (c *cache) List() []interface{} { // Get returns the requested item, or sets exists=false. // Get is completely threadsafe as long as you treat all items as immutable. func (c *cache) Get(obj interface{}) (item interface{}, exists bool, err error) { - id, _ := c.keyFunc(obj) + key, _ := c.keyFunc(obj) if err != nil { return nil, false, fmt.Errorf("couldn't create key for object: %v", err) } + return c.GetByKey(key) +} + +// GetByKey returns the request item, or exists=false. +// GetByKey is completely threadsafe as long as you treat all items as immutable. +func (c *cache) GetByKey(key string) (item interface{}, exists bool, err error) { c.lock.RLock() defer c.lock.RUnlock() - item, exists = c.items[id] + item, exists = c.items[key] return item, exists, nil } diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/undelta_store.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/undelta_store.go index 09299fbd34a7..70adda90c343 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/undelta_store.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache/undelta_store.go @@ -69,6 +69,9 @@ func (u *UndeltaStore) List() []interface{} { func (u *UndeltaStore) Get(obj interface{}) (item interface{}, exists bool, err error) { return u.ActualStore.Get(obj) } +func (u *UndeltaStore) GetByKey(key string) (item interface{}, exists bool, err error) { + return u.ActualStore.GetByKey(key) +} func (u *UndeltaStore) Replace(list []interface{}) error { if err := u.ActualStore.Replace(list); err != nil { return err From 8046080bd97e535f2b01ef86514838bc04f1ce7f Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Sat, 31 Jan 2015 22:46:32 -0500 Subject: [PATCH 08/12] UPSTREAM: Relax validation around annotations --- .../pkg/api/validation/validation.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation/validation.go b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation/validation.go index 2271f8e20eaa..394feb2ee787 100644 --- a/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation/validation.go +++ b/Godeps/_workspace/src/github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation/validation.go @@ -71,7 +71,7 @@ func ValidateObjectMeta(meta *api.ObjectMeta, requiresNamespace bool, nameFn Val } } allErrs = append(allErrs, ValidateLabels(meta.Labels, "labels")...) - allErrs = append(allErrs, ValidateLabels(meta.Annotations, "annotations")...) + allErrs = append(allErrs, ValidateAnnotations(meta.Annotations, "annotations")...) // Clear self link internally // TODO: move to its own area @@ -106,7 +106,7 @@ func ValidateObjectMetaUpdate(old, meta *api.ObjectMeta) errs.ValidationErrorLis } allErrs = append(allErrs, ValidateLabels(meta.Labels, "labels")...) - allErrs = append(allErrs, ValidateLabels(meta.Annotations, "annotations")...) + allErrs = append(allErrs, ValidateAnnotations(meta.Annotations, "annotations")...) // Clear self link internally // TODO: move to its own area @@ -501,6 +501,17 @@ func ValidateLabels(labels map[string]string, field string) errs.ValidationError return allErrs } +// ValidateAnnotations validates that a set of annotations are correctly defined. +func ValidateAnnotations(labels map[string]string, field string) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + for k := range labels { + if !util.IsQualifiedName(strings.ToLower(k)) { + allErrs = append(allErrs, errs.NewFieldInvalid(field, k, "")) + } + } + return allErrs +} + // ValidatePodUpdate tests to see if the update is legal func ValidatePodUpdate(newPod, oldPod *api.Pod) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} @@ -607,7 +618,7 @@ func ValidateReplicationControllerSpec(spec *api.ReplicationControllerSpec) errs if !selector.Matches(labels) { allErrs = append(allErrs, errs.NewFieldInvalid("template.labels", spec.Template.Labels, "selector does not match template")) } - allErrs = append(allErrs, ValidateLabels(spec.Template.Annotations, "annotations")...) + allErrs = append(allErrs, ValidateAnnotations(spec.Template.Annotations, "annotations")...) allErrs = append(allErrs, ValidatePodTemplateSpec(spec.Template).Prefix("template")...) // RestartPolicy has already been first-order validated as per ValidatePodTemplateSpec(). if spec.Template.Spec.RestartPolicy.Always == nil { @@ -623,7 +634,7 @@ func ValidateReplicationControllerSpec(spec *api.ReplicationControllerSpec) errs func ValidatePodTemplateSpec(spec *api.PodTemplateSpec) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} allErrs = append(allErrs, ValidateLabels(spec.Labels, "labels")...) - allErrs = append(allErrs, ValidateLabels(spec.Annotations, "annotations")...) + allErrs = append(allErrs, ValidateAnnotations(spec.Annotations, "annotations")...) allErrs = append(allErrs, ValidatePodSpec(&spec.Spec).Prefix("spec")...) allErrs = append(allErrs, ValidateReadOnlyPersistentDisks(spec.Spec.Volumes).Prefix("spec.volumes")...) return allErrs From fa5b55e98c20670b8f20aa8b678f58f49d1a114e Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Sun, 1 Feb 2015 14:48:11 -0500 Subject: [PATCH 09/12] Adapt to upstream changes for cache.Store --- pkg/build/controller/factory/factory.go | 10 +- .../test/fake_build_config_store.go | 37 +++-- pkg/build/controller/test/fake_build_store.go | 29 +++- pkg/client/cache/eventqueue.go | 147 +++++++++++------- pkg/client/cache/eventqueue_test.go | 127 ++++++++------- .../controller/config_change_controller.go | 5 +- .../controller/deployment_controller.go | 6 +- pkg/deploy/controller/factory/factory.go | 16 +- .../test/fake_deployment_config_store.go | 47 ++++-- .../controller/test/fake_deployment_store.go | 38 ++++- pkg/router/controller/controller.go | 16 +- pkg/router/controller/factory/factory.go | 22 ++- 12 files changed, 319 insertions(+), 181 deletions(-) diff --git a/pkg/build/controller/factory/factory.go b/pkg/build/controller/factory/factory.go index 2c7b776c314c..f0ca792c7fad 100644 --- a/pkg/build/controller/factory/factory.go +++ b/pkg/build/controller/factory/factory.go @@ -35,10 +35,10 @@ type BuildControllerFactory struct { } func (factory *BuildControllerFactory) Create() *controller.BuildController { - factory.buildStore = cache.NewStore() + factory.buildStore = cache.NewStore(cache.MetaNamespaceKeyFunc) cache.NewReflector(&buildLW{client: factory.OSClient}, &buildapi.Build{}, factory.buildStore).RunUntil(factory.Stop) - buildQueue := cache.NewFIFO() + buildQueue := cache.NewFIFO(cache.MetaNamespaceKeyFunc) cache.NewReflector(&buildLW{client: factory.OSClient}, &buildapi.Build{}, buildQueue).RunUntil(factory.Stop) // Kubernetes does not currently synchronize Pod status in storage with a Pod's container @@ -49,7 +49,7 @@ func (factory *BuildControllerFactory) Create() *controller.BuildController { // // TODO: Find a way to get watch events for Pod/container status updates. The polling // strategy is horribly inefficient and should be addressed upstream somehow. - podQueue := cache.NewFIFO() + podQueue := cache.NewFIFO(cache.MetaNamespaceKeyFunc) cache.NewPoller(factory.pollPods, 10*time.Second, podQueue).RunUntil(factory.Stop) client := ControllerClient{factory.KubeClient, factory.OSClient} @@ -89,10 +89,10 @@ type ImageChangeControllerFactory struct { // Create creates a new ImageChangeController which is used to trigger builds when a new // image is available func (factory *ImageChangeControllerFactory) Create() *controller.ImageChangeController { - queue := cache.NewFIFO() + queue := cache.NewFIFO(cache.MetaNamespaceKeyFunc) cache.NewReflector(&imageRepositoryLW{factory.Client}, &imageapi.ImageRepository{}, queue).RunUntil(factory.Stop) - store := cache.NewStore() + store := cache.NewStore(cache.MetaNamespaceKeyFunc) cache.NewReflector(&buildConfigLW{client: factory.Client}, &buildapi.BuildConfig{}, store).RunUntil(factory.Stop) return &controller.ImageChangeController{ diff --git a/pkg/build/controller/test/fake_build_config_store.go b/pkg/build/controller/test/fake_build_config_store.go index d2e4a7a26507..86fcb51b7091 100644 --- a/pkg/build/controller/test/fake_build_config_store.go +++ b/pkg/build/controller/test/fake_build_config_store.go @@ -6,36 +6,49 @@ import ( ) type FakeBuildConfigStore struct { - BuildConfig *buildapi.BuildConfig + Build *buildapi.BuildConfig + Err error } -func NewFakeBuildConfigStore(buildcfg *buildapi.BuildConfig) FakeBuildConfigStore { - return FakeBuildConfigStore{buildcfg} +func NewFakeBuildConfigStore(build *buildapi.BuildConfig) FakeBuildConfigStore { + return FakeBuildConfigStore{Build: build} } -func (s FakeBuildConfigStore) Add(id string, obj interface{}) { +func (s FakeBuildConfigStore) Add(obj interface{}) error { + return s.Err } -func (s FakeBuildConfigStore) Update(id string, obj interface{}) { +func (s FakeBuildConfigStore) Update(obj interface{}) error { + return s.Err } -func (s FakeBuildConfigStore) Delete(id string) { +func (s FakeBuildConfigStore) Delete(obj interface{}) error { + return s.Err } func (s FakeBuildConfigStore) List() []interface{} { - return []interface{}{s.BuildConfig} + return []interface{}{s.Build} } func (s FakeBuildConfigStore) ContainedIDs() util.StringSet { return util.NewStringSet() } -func (s FakeBuildConfigStore) Get(id string) (item interface{}, exists bool) { - if s.BuildConfig == nil { - return nil, false +func (s FakeBuildConfigStore) Get(obj interface{}) (item interface{}, exists bool, err error) { + return s.GetByKey("") +} + +func (s FakeBuildConfigStore) GetByKey(id string) (item interface{}, exists bool, err error) { + if s.Err != nil { + return nil, false, err + } + if s.Build == nil { + return nil, false, nil } - return s.BuildConfig, true + return s.Build, true, nil } -func (s FakeBuildConfigStore) Replace(idToObj map[string]interface{}) {} +func (s FakeBuildConfigStore) Replace(list []interface{}) error { + return nil +} diff --git a/pkg/build/controller/test/fake_build_store.go b/pkg/build/controller/test/fake_build_store.go index 5a8c27673d85..06d29b1e2e99 100644 --- a/pkg/build/controller/test/fake_build_store.go +++ b/pkg/build/controller/test/fake_build_store.go @@ -7,19 +7,23 @@ import ( type FakeBuildStore struct { Build *buildapi.Build + Err error } func NewFakeBuildStore(build *buildapi.Build) FakeBuildStore { - return FakeBuildStore{build} + return FakeBuildStore{Build: build} } -func (s FakeBuildStore) Add(id string, obj interface{}) { +func (s FakeBuildStore) Add(obj interface{}) error { + return s.Err } -func (s FakeBuildStore) Update(id string, obj interface{}) { +func (s FakeBuildStore) Update(obj interface{}) error { + return s.Err } -func (s FakeBuildStore) Delete(id string) { +func (s FakeBuildStore) Delete(obj interface{}) error { + return s.Err } func (s FakeBuildStore) List() []interface{} { @@ -30,12 +34,21 @@ func (s FakeBuildStore) ContainedIDs() util.StringSet { return util.NewStringSet() } -func (s FakeBuildStore) Get(id string) (item interface{}, exists bool) { +func (s FakeBuildStore) Get(obj interface{}) (item interface{}, exists bool, err error) { + return s.GetByKey("") +} + +func (s FakeBuildStore) GetByKey(id string) (item interface{}, exists bool, err error) { + if s.Err != nil { + return nil, false, err + } if s.Build == nil { - return nil, false + return nil, false, nil } - return s.Build, true + return s.Build, true, nil } -func (s FakeBuildStore) Replace(idToObj map[string]interface{}) {} +func (s FakeBuildStore) Replace(list []interface{}) error { + return nil +} diff --git a/pkg/client/cache/eventqueue.go b/pkg/client/cache/eventqueue.go index c4435a93146e..f5850380dc9e 100644 --- a/pkg/client/cache/eventqueue.go +++ b/pkg/client/cache/eventqueue.go @@ -39,6 +39,7 @@ type EventQueue struct { lock sync.RWMutex cond sync.Cond store kcache.Store + keyFn kcache.KeyFunc events map[string]watch.EventType queue []string } @@ -87,7 +88,12 @@ var watchEventCompressionMatrix = map[watch.EventType]map[watch.EventType]watch. // handleEvent is called by Add, Update, and Delete to determine the effect // of an event of the queue, realize that effect, and update the underlying store. -func (eq *EventQueue) handleEvent(id string, obj interface{}, newEventType watch.EventType) { +func (eq *EventQueue) handleEvent(obj interface{}, newEventType watch.EventType) error { + key, err := eq.keyFn(obj) + if err != nil { + return err + } + eq.lock.Lock() defer eq.lock.Unlock() @@ -97,7 +103,7 @@ func (eq *EventQueue) handleEvent(id string, obj interface{}, newEventType watch ok bool ) - queuedEventType, ok = eq.events[id] + queuedEventType, ok = eq.events[key] if !ok { effect = watchEventEffectAdd } else { @@ -107,12 +113,14 @@ func (eq *EventQueue) handleEvent(id string, obj interface{}, newEventType watch } } - eq.updateStore(id, obj, newEventType) + if err := eq.updateStore(key, obj, newEventType); err != nil { + return err + } switch effect { case watchEventEffectAdd: - eq.events[id] = newEventType - eq.queue = append(eq.queue, id) + eq.events[key] = newEventType + eq.queue = append(eq.queue, key) eq.cond.Broadcast() case watchEventEffectCompress: newEventType, ok := watchEventCompressionMatrix[queuedEventType][newEventType] @@ -120,54 +128,57 @@ func (eq *EventQueue) handleEvent(id string, obj interface{}, newEventType watch panic(fmt.Sprintf("Invalid state transition: %v -> %v", queuedEventType, newEventType)) } - eq.events[id] = newEventType + eq.events[key] = newEventType case watchEventEffectDelete: - delete(eq.events, id) - eq.queue = eq.queueWithout(id) + delete(eq.events, key) + eq.queue = eq.queueWithout(key) } + return nil } -// updateStore updates the stored value for the given id. Note that deletions are not handled +// updateStore updates the stored value for the given key. Note that deletions are not handled // here; they are performed in Pop in order to provide the deleted value on watch.Deleted events. -func (eq *EventQueue) updateStore(id string, obj interface{}, eventType watch.EventType) { +func (eq *EventQueue) updateStore(key string, obj interface{}, eventType watch.EventType) error { if eventType == watch.Deleted { - return + return nil } + var err error if eventType == watch.Added { - eq.store.Add(id, obj) + err = eq.store.Add(obj) } else { - eq.store.Update(id, obj) + err = eq.store.Update(obj) } + return err } -// queueWithout returns the internal queue minus the given id. -func (eq *EventQueue) queueWithout(id string) []string { +// queueWithout returns the internal queue minus the given key. +func (eq *EventQueue) queueWithout(key string) []string { rq := make([]string, 0) - for _, qid := range eq.queue { - if qid == id { + for _, qkey := range eq.queue { + if qkey == key { continue } - rq = append(rq, qid) + rq = append(rq, qkey) } return rq } -// Add enqueues a watch.Added event for the given id and state. -func (eq *EventQueue) Add(id string, obj interface{}) { - eq.handleEvent(id, obj, watch.Added) +// Add enqueues a watch.Added event for the given state. +func (eq *EventQueue) Add(obj interface{}) error { + return eq.handleEvent(obj, watch.Added) } -// Update enqueues a watch.Modified event for the given id and state. -func (eq *EventQueue) Update(id string, obj interface{}) { - eq.handleEvent(id, obj, watch.Modified) +// Update enqueues a watch.Modified event for the given state. +func (eq *EventQueue) Update(obj interface{}) error { + return eq.handleEvent(obj, watch.Modified) } -// Delete enqueues a watch.Delete event for the given id. -func (eq *EventQueue) Delete(id string) { - eq.handleEvent(id, nil, watch.Deleted) +// Delete enqueues a watch.Delete event for the given object. +func (eq *EventQueue) Delete(obj interface{}) error { + return eq.handleEvent(obj, watch.Deleted) } // List returns a list of all enqueued items. @@ -175,16 +186,14 @@ func (eq *EventQueue) List() []interface{} { eq.lock.RLock() defer eq.lock.RUnlock() - var ( - item interface{} - ok bool - ) - list := make([]interface{}, 0, len(eq.queue)) - for _, id := range eq.queue { - item, ok = eq.store.Get(id) + for _, key := range eq.queue { + item, ok, err := eq.store.GetByKey(key) + if err != nil { + panic(fmt.Sprintf("Failure to get by key %q: %v", key, err)) + } if !ok { - panic(fmt.Sprintf("Tried to list an ID not in backing store: %v", id)) + panic(fmt.Sprintf("Tried to list an ID not in backing store: %v", key)) } list = append(list, item) } @@ -200,29 +209,38 @@ func (eq *EventQueue) ContainedIDs() util.StringSet { defer eq.lock.RUnlock() s := util.StringSet{} - for _, id := range eq.queue { - s.Insert(id) + for _, key := range eq.queue { + s.Insert(key) } return s } // Get returns the requested item, or sets exists=false. -func (eq *EventQueue) Get(id string) (item interface{}, exists bool) { +func (eq *EventQueue) Get(obj interface{}) (item interface{}, exists bool, err error) { + key, err := eq.keyFn(obj) + if err != nil { + return nil, false, err + } + return eq.GetByKey(key) +} + +// Get returns the requested item, or sets exists=false. +func (eq *EventQueue) GetByKey(key string) (item interface{}, exists bool, err error) { eq.lock.RLock() defer eq.lock.RUnlock() - _, ok := eq.events[id] + _, ok := eq.events[key] if !ok { - return nil, false + return nil, false, nil } - return eq.store.Get(id) // Should always be populated and succeed + return eq.store.GetByKey(key) // Should always be populated and succeed } // Pop gets the event and object at the head of the queue. If the event -// is a delete event, Pop deletes the id from the underlying cache. -func (eq *EventQueue) Pop() (watch.EventType, interface{}) { +// is a delete event, Pop deletes the key from the underlying cache. +func (eq *EventQueue) Pop() (watch.EventType, interface{}, error) { eq.lock.Lock() defer eq.lock.Unlock() @@ -231,53 +249,66 @@ func (eq *EventQueue) Pop() (watch.EventType, interface{}) { eq.cond.Wait() } - id := eq.queue[0] + key := eq.queue[0] eq.queue = eq.queue[1:] - eventType := eq.events[id] - delete(eq.events, id) + eventType := eq.events[key] + delete(eq.events, key) - obj, exists := eq.store.Get(id) // Should always succeed + obj, exists, err := eq.store.GetByKey(key) // Should always succeed + if err != nil { + return watch.Error, nil, err + } if !exists { - panic(fmt.Sprintf("Pop() of id not in store: %v", id)) + panic(fmt.Sprintf("Pop() of key not in store: %v", key)) } if eventType == watch.Deleted { - eq.store.Delete(id) + if err := eq.store.Delete(obj); err != nil { + return watch.Error, nil, err + } } - return eventType, obj + return eventType, obj, nil } } // Replace initializes 'eq' with the state contained in the given map and // populates the queue with a watch.Modified event for each of the replaced -// objects. The backing store takes ownership of idToObjs; you should not +// objects. The backing store takes ownership of keyToObjs; you should not // reference the map again after calling this function. -func (eq *EventQueue) Replace(idToObjs map[string]interface{}) { +func (eq *EventQueue) Replace(objects []interface{}) error { eq.lock.Lock() defer eq.lock.Unlock() eq.events = map[string]watch.EventType{} eq.queue = eq.queue[:0] - for id := range idToObjs { - eq.queue = append(eq.queue, id) - eq.events[id] = watch.Modified + for i := range objects { + key, err := eq.keyFn(objects[i]) + if err != nil { + return err + } + eq.queue = append(eq.queue, key) + eq.events[key] = watch.Modified + } + if err := eq.store.Replace(objects); err != nil { + return err } - eq.store.Replace(idToObjs) if len(eq.queue) > 0 { eq.cond.Broadcast() } + return nil } // NewEventQueue returns a new EventQueue ready for action. -func NewEventQueue() *EventQueue { +func NewEventQueue(keyFn kcache.KeyFunc) *EventQueue { q := &EventQueue{ - store: kcache.NewStore(), + store: kcache.NewStore(keyFn), events: map[string]watch.EventType{}, queue: []string{}, + keyFn: keyFn, } q.cond.L = &q.lock return q diff --git a/pkg/client/cache/eventqueue_test.go b/pkg/client/cache/eventqueue_test.go index b002108966a7..a1fc7082b590 100644 --- a/pkg/client/cache/eventqueue_test.go +++ b/pkg/client/cache/eventqueue_test.go @@ -22,37 +22,46 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/watch" ) +type cacheable struct { + key string + value interface{} +} + +func keyFunc(obj interface{}) (string, error) { + return obj.(cacheable).key, nil +} + func TestEventQueue_basic(t *testing.T) { - q := NewEventQueue() + q := NewEventQueue(keyFunc) const amount = 500 go func() { for i := 0; i < amount; i++ { - q.Add(string([]rune{'a', rune(i)}), i+1) + q.Add(cacheable{string([]rune{'a', rune(i)}), i + 1}) } }() go func() { for u := uint(0); u < amount; u++ { - q.Add(string([]rune{'b', rune(u)}), u+1) + q.Add(cacheable{string([]rune{'b', rune(u)}), u + 1}) } }() lastInt := int(0) lastUint := uint(0) for i := 0; i < amount*2; i++ { - _, obj := q.Pop() - - switch obj.(type) { + _, obj, _ := q.Pop() + value := obj.(cacheable).value + switch v := value.(type) { case int: - if obj.(int) <= lastInt { - t.Errorf("got %v (int) out of order, last was %v", obj, lastInt) + if v <= lastInt { + t.Errorf("got %v (int) out of order, last was %v", v, lastInt) } - lastInt = obj.(int) + lastInt = v case uint: - if obj.(uint) <= lastUint { - t.Errorf("got %v (uint) out of order, last was %v", obj, lastUint) + if v <= lastUint { + t.Errorf("got %v (uint) out of order, last was %v", v, lastUint) } else { - lastUint = obj.(uint) + lastUint = v } default: t.Fatalf("unexpected type %#v", obj) @@ -61,17 +70,18 @@ func TestEventQueue_basic(t *testing.T) { } func TestEventQueue_initialEventIsDelete(t *testing.T) { - q := NewEventQueue() + q := NewEventQueue(keyFunc) - q.Replace(map[string]interface{}{ - "foo": 2, + q.Replace([]interface{}{ + cacheable{"foo", 2}, }) - q.Delete("foo") + q.Delete(cacheable{key: "foo"}) - event, thing := q.Pop() + event, thing, _ := q.Pop() - if thing != 2 { + value := thing.(cacheable).value + if value != 2 { t.Fatalf("expected %v, got %v", 2, thing) } @@ -81,16 +91,17 @@ func TestEventQueue_initialEventIsDelete(t *testing.T) { } func TestEventQueue_compressAddDelete(t *testing.T) { - q := NewEventQueue() + q := NewEventQueue(keyFunc) - q.Add("foo", 10) - q.Delete("foo") - q.Add("zab", 30) + q.Add(cacheable{"foo", 10}) + q.Delete(cacheable{key: "foo"}) + q.Add(cacheable{"zab", 30}) - event, thing := q.Pop() + event, thing, _ := q.Pop() - if thing != 30 { - t.Fatalf("expected %v, got %v", 30, thing) + value := thing.(cacheable).value + if value != 30 { + t.Fatalf("expected %v, got %v", 30, value) } if event != watch.Added { @@ -99,15 +110,15 @@ func TestEventQueue_compressAddDelete(t *testing.T) { } func TestEventQueue_compressAddUpdate(t *testing.T) { - q := NewEventQueue() + q := NewEventQueue(keyFunc) - q.Add("foo", 10) - q.Update("foo", 11) + q.Add(cacheable{"foo", 10}) + q.Update(cacheable{"foo", 11}) - event, thing := q.Pop() - - if thing != 11 { - t.Fatalf("expected %v, got %v", 11, thing) + event, thing, _ := q.Pop() + value := thing.(cacheable).value + if value != 11 { + t.Fatalf("expected %v, got %v", 11, value) } if event != watch.Added { @@ -116,19 +127,19 @@ func TestEventQueue_compressAddUpdate(t *testing.T) { } func TestEventQueue_compressTwoUpdates(t *testing.T) { - q := NewEventQueue() + q := NewEventQueue(keyFunc) - q.Replace(map[string]interface{}{ - "foo": 2, + q.Replace([]interface{}{ + cacheable{"foo", 2}, }) - q.Update("foo", 3) - q.Update("foo", 4) - - event, thing := q.Pop() + q.Update(cacheable{"foo", 3}) + q.Update(cacheable{"foo", 4}) - if thing != 4 { - t.Fatalf("expected %v, got %v", 4, thing) + event, thing, _ := q.Pop() + value := thing.(cacheable).value + if value != 4 { + t.Fatalf("expected %v, got %v", 4, value) } if event != watch.Modified { @@ -137,19 +148,19 @@ func TestEventQueue_compressTwoUpdates(t *testing.T) { } func TestEventQueue_compressUpdateDelete(t *testing.T) { - q := NewEventQueue() + q := NewEventQueue(keyFunc) - q.Replace(map[string]interface{}{ - "foo": 2, + q.Replace([]interface{}{ + cacheable{"foo", 2}, }) - q.Update("foo", 3) - q.Delete("foo") + q.Update(cacheable{"foo", 3}) + q.Delete(cacheable{key: "foo"}) - event, thing := q.Pop() - - if thing != 3 { - t.Fatalf("expected %v, got %v", 3, thing) + event, thing, _ := q.Pop() + value := thing.(cacheable).value + if value != 3 { + t.Fatalf("expected %v, got %v", 3, value) } if event != watch.Deleted { @@ -158,18 +169,18 @@ func TestEventQueue_compressUpdateDelete(t *testing.T) { } func TestEventQueue_modifyEventsFromReplace(t *testing.T) { - q := NewEventQueue() + q := NewEventQueue(keyFunc) - q.Replace(map[string]interface{}{ - "foo": 2, + q.Replace([]interface{}{ + cacheable{"foo", 2}, }) - q.Update("foo", 2) - - event, thing := q.Pop() + q.Update(cacheable{"foo", 2}) - if thing != 2 { - t.Fatalf("expected %v, got %v", 3, thing) + event, thing, _ := q.Pop() + value := thing.(cacheable).value + if value != 2 { + t.Fatalf("expected %v, got %v", 2, value) } if event != watch.Modified { diff --git a/pkg/deploy/controller/config_change_controller.go b/pkg/deploy/controller/config_change_controller.go index 32423031dae8..3e58dc539b24 100644 --- a/pkg/deploy/controller/config_change_controller.go +++ b/pkg/deploy/controller/config_change_controller.go @@ -58,7 +58,10 @@ func (dc *DeploymentConfigChangeController) HandleDeploymentConfig() { } latestDeploymentID := deployutil.LatestDeploymentNameForConfig(config) - obj, exists := dc.DeploymentStore.Get(latestDeploymentID) + obj, exists, err := dc.DeploymentStore.Get(&kapi.ReplicationController{ObjectMeta: kapi.ObjectMeta{Name: latestDeploymentID, Namespace: config.Namespace}}) + if err != nil { + glog.Errorf("Unable to retrieve deployment from store: %v", err) + } if !exists { glog.V(4).Info("Ignoring config change due to lack of existing deployment") diff --git a/pkg/deploy/controller/deployment_controller.go b/pkg/deploy/controller/deployment_controller.go index 18441a22b731..4b3af9648ddf 100644 --- a/pkg/deploy/controller/deployment_controller.go +++ b/pkg/deploy/controller/deployment_controller.go @@ -118,7 +118,11 @@ func (dc *DeploymentController) HandlePod() { return } - deploymentObj, deploymentExists := dc.DeploymentStore.Get(deploymentID) + deploymentObj, deploymentExists, err := dc.DeploymentStore.Get(&kapi.ReplicationController{ObjectMeta: kapi.ObjectMeta{Name: deploymentID, Namespace: pod.Namespace}}) + if err != nil { + glog.Errorf("Unable to retrieve deployment from store: %v", err) + return + } if !deploymentExists { glog.V(2).Infof("Couldn't find deployment %s associated with pod %s", deploymentID, pod.Name) return diff --git a/pkg/deploy/controller/factory/factory.go b/pkg/deploy/controller/factory/factory.go index fd7a4b1571fe..f89c4b807fc9 100644 --- a/pkg/deploy/controller/factory/factory.go +++ b/pkg/deploy/controller/factory/factory.go @@ -28,7 +28,7 @@ type DeploymentConfigControllerFactory struct { } func (factory *DeploymentConfigControllerFactory) Create() *controller.DeploymentConfigController { - queue := cache.NewFIFO() + queue := cache.NewFIFO(cache.MetaNamespaceKeyFunc) cache.NewReflector(&deploymentConfigLW{factory.Client}, &deployapi.DeploymentConfig{}, queue).RunUntil(factory.Stop) return &controller.DeploymentConfigController{ @@ -67,10 +67,10 @@ type DeploymentControllerFactory struct { } func (factory *DeploymentControllerFactory) Create() *controller.DeploymentController { - deploymentQueue := cache.NewFIFO() + deploymentQueue := cache.NewFIFO(cache.MetaNamespaceKeyFunc) cache.NewReflector(&deploymentLW{client: factory.KubeClient, field: labels.Everything()}, &kapi.ReplicationController{}, deploymentQueue).RunUntil(factory.Stop) - factory.deploymentStore = cache.NewStore() + factory.deploymentStore = cache.NewStore(cache.MetaNamespaceKeyFunc) cache.NewReflector(&deploymentLW{client: factory.KubeClient, field: labels.Everything()}, &kapi.ReplicationController{}, factory.deploymentStore).RunUntil(factory.Stop) // Kubernetes does not currently synchronize Pod status in storage with a Pod's container @@ -81,7 +81,7 @@ func (factory *DeploymentControllerFactory) Create() *controller.DeploymentContr // // TODO: Find a way to get watch events for Pod/container status updates. The polling // strategy is horribly inefficient and should be addressed upstream somehow. - podQueue := cache.NewFIFO() + podQueue := cache.NewFIFO(cache.MetaNamespaceKeyFunc) cache.NewPoller(factory.pollPods, 10*time.Second, podQueue).RunUntil(factory.Stop) return &controller.DeploymentController{ @@ -200,10 +200,10 @@ type DeploymentConfigChangeControllerFactory struct { } func (factory *DeploymentConfigChangeControllerFactory) Create() *controller.DeploymentConfigChangeController { - queue := cache.NewFIFO() + queue := cache.NewFIFO(cache.MetaNamespaceKeyFunc) cache.NewReflector(&deploymentConfigLW{factory.Client}, &deployapi.DeploymentConfig{}, queue).RunUntil(factory.Stop) - store := cache.NewStore() + store := cache.NewStore(cache.MetaNamespaceKeyFunc) cache.NewReflector(&deploymentLW{client: factory.KubeClient, field: labels.Everything()}, &kapi.ReplicationController{}, store).RunUntil(factory.Stop) return &controller.DeploymentConfigChangeController{ @@ -228,10 +228,10 @@ type ImageChangeControllerFactory struct { } func (factory *ImageChangeControllerFactory) Create() *controller.ImageChangeController { - queue := cache.NewFIFO() + queue := cache.NewFIFO(cache.MetaNamespaceKeyFunc) cache.NewReflector(&imageRepositoryLW{factory.Client}, &imageapi.ImageRepository{}, queue).RunUntil(factory.Stop) - store := cache.NewStore() + store := cache.NewStore(cache.MetaNamespaceKeyFunc) cache.NewReflector(&deploymentConfigLW{factory.Client}, &deployapi.DeploymentConfig{}, store).RunUntil(factory.Stop) return &controller.ImageChangeController{ diff --git a/pkg/deploy/controller/test/fake_deployment_config_store.go b/pkg/deploy/controller/test/fake_deployment_config_store.go index a5c6df060b52..7fdb608965df 100644 --- a/pkg/deploy/controller/test/fake_deployment_config_store.go +++ b/pkg/deploy/controller/test/fake_deployment_config_store.go @@ -2,27 +2,54 @@ package test import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/util" - deployapi "github.com/openshift/origin/pkg/deploy/api" + + "github.com/openshift/origin/pkg/deploy/api" ) type FakeDeploymentConfigStore struct { - DeploymentConfig *deployapi.DeploymentConfig + DeploymentConfig *api.DeploymentConfig + Err error +} + +func NewFakeDeploymentConfigStore(deployment *api.DeploymentConfig) FakeDeploymentConfigStore { + return FakeDeploymentConfigStore{DeploymentConfig: deployment} +} + +func (s FakeDeploymentConfigStore) Add(obj interface{}) error { + return s.Err +} + +func (s FakeDeploymentConfigStore) Update(obj interface{}) error { + return s.Err } -func NewFakeDeploymentConfigStore(config *deployapi.DeploymentConfig) FakeDeploymentConfigStore { - return FakeDeploymentConfigStore{config} +func (s FakeDeploymentConfigStore) Delete(obj interface{}) error { + return s.Err } -func (s FakeDeploymentConfigStore) Add(id string, obj interface{}) {} -func (s FakeDeploymentConfigStore) Update(id string, obj interface{}) {} -func (s FakeDeploymentConfigStore) Delete(id string) {} func (s FakeDeploymentConfigStore) List() []interface{} { return []interface{}{s.DeploymentConfig} } + func (s FakeDeploymentConfigStore) ContainedIDs() util.StringSet { return util.NewStringSet() } -func (s FakeDeploymentConfigStore) Get(id string) (item interface{}, exists bool) { - return nil, false + +func (s FakeDeploymentConfigStore) Get(obj interface{}) (item interface{}, exists bool, err error) { + return s.GetByKey("") +} + +func (s FakeDeploymentConfigStore) GetByKey(id string) (item interface{}, exists bool, err error) { + if s.Err != nil { + return nil, false, err + } + if s.DeploymentConfig == nil { + return nil, false, nil + } + + return s.DeploymentConfig, true, nil +} + +func (s FakeDeploymentConfigStore) Replace(list []interface{}) error { + return nil } -func (s FakeDeploymentConfigStore) Replace(idToObj map[string]interface{}) {} diff --git a/pkg/deploy/controller/test/fake_deployment_store.go b/pkg/deploy/controller/test/fake_deployment_store.go index 66400569e48e..4b567d10db5d 100644 --- a/pkg/deploy/controller/test/fake_deployment_store.go +++ b/pkg/deploy/controller/test/fake_deployment_store.go @@ -7,26 +7,48 @@ import ( type FakeDeploymentStore struct { Deployment *kapi.ReplicationController + Err error } func NewFakeDeploymentStore(deployment *kapi.ReplicationController) FakeDeploymentStore { - return FakeDeploymentStore{deployment} + return FakeDeploymentStore{Deployment: deployment} +} + +func (s FakeDeploymentStore) Add(obj interface{}) error { + return s.Err +} + +func (s FakeDeploymentStore) Update(obj interface{}) error { + return s.Err +} + +func (s FakeDeploymentStore) Delete(obj interface{}) error { + return s.Err } -func (s FakeDeploymentStore) Add(id string, obj interface{}) {} -func (s FakeDeploymentStore) Update(id string, obj interface{}) {} -func (s FakeDeploymentStore) Delete(id string) {} func (s FakeDeploymentStore) List() []interface{} { return []interface{}{s.Deployment} } + func (s FakeDeploymentStore) ContainedIDs() util.StringSet { return util.NewStringSet() } -func (s FakeDeploymentStore) Get(id string) (item interface{}, exists bool) { + +func (s FakeDeploymentStore) Get(obj interface{}) (item interface{}, exists bool, err error) { + return s.GetByKey("") +} + +func (s FakeDeploymentStore) GetByKey(id string) (item interface{}, exists bool, err error) { + if s.Err != nil { + return nil, false, err + } if s.Deployment == nil { - return nil, false + return nil, false, nil } - return s.Deployment, true + return s.Deployment, true, nil +} + +func (s FakeDeploymentStore) Replace(list []interface{}) error { + return nil } -func (s FakeDeploymentStore) Replace(idToObj map[string]interface{}) {} diff --git a/pkg/router/controller/controller.go b/pkg/router/controller/controller.go index 1af3be2a92fb..5efd9762a070 100644 --- a/pkg/router/controller/controller.go +++ b/pkg/router/controller/controller.go @@ -17,8 +17,8 @@ import ( type RouterController struct { lock sync.Mutex Plugin router.Plugin - NextRoute func() (watch.EventType, *routeapi.Route) - NextEndpoints func() (watch.EventType, *kapi.Endpoints) + NextRoute func() (watch.EventType, *routeapi.Route, error) + NextEndpoints func() (watch.EventType, *kapi.Endpoints, error) } // Run begins watching and syncing. @@ -30,7 +30,11 @@ func (c *RouterController) Run() { // HandleRoute handles a single Route event and synchronizes the router backend. func (c *RouterController) HandleRoute() { - eventType, route := c.NextRoute() + eventType, route, err := c.NextRoute() + if err != nil { + glog.Errorf("Unable to read routes: %v", err) + return + } c.lock.Lock() defer c.lock.Unlock() @@ -44,7 +48,11 @@ func (c *RouterController) HandleRoute() { // HandleEndpoints handles a single Endpoints event and refreshes the router backend. func (c *RouterController) HandleEndpoints() { - eventType, endpoints := c.NextEndpoints() + eventType, endpoints, err := c.NextEndpoints() + if err != nil { + glog.Errorf("Unable to read endpoints: %v", err) + return + } c.lock.Lock() defer c.lock.Unlock() diff --git a/pkg/router/controller/factory/factory.go b/pkg/router/controller/factory/factory.go index d55a97465a9a..a63af7eebff2 100644 --- a/pkg/router/controller/factory/factory.go +++ b/pkg/router/controller/factory/factory.go @@ -21,21 +21,27 @@ type RouterControllerFactory struct { } func (factory *RouterControllerFactory) Create(plugin router.Plugin) *controller.RouterController { - routeEventQueue := oscache.NewEventQueue() + routeEventQueue := oscache.NewEventQueue(cache.MetaNamespaceKeyFunc) cache.NewReflector(&routeLW{factory.OSClient}, &routeapi.Route{}, routeEventQueue).Run() - endpointsEventQueue := oscache.NewEventQueue() + endpointsEventQueue := oscache.NewEventQueue(cache.MetaNamespaceKeyFunc) cache.NewReflector(&endpointsLW{factory.KClient}, &kapi.Endpoints{}, endpointsEventQueue).Run() return &controller.RouterController{ Plugin: plugin, - NextEndpoints: func() (watch.EventType, *kapi.Endpoints) { - eventType, obj := endpointsEventQueue.Pop() - return eventType, obj.(*kapi.Endpoints) + NextEndpoints: func() (watch.EventType, *kapi.Endpoints, error) { + eventType, obj, err := endpointsEventQueue.Pop() + if err != nil { + return watch.Error, nil, err + } + return eventType, obj.(*kapi.Endpoints), nil }, - NextRoute: func() (watch.EventType, *routeapi.Route) { - eventType, obj := routeEventQueue.Pop() - return eventType, obj.(*routeapi.Route) + NextRoute: func() (watch.EventType, *routeapi.Route, error) { + eventType, obj, err := routeEventQueue.Pop() + if err != nil { + return watch.Error, nil, err + } + return eventType, obj.(*routeapi.Route), nil }, } } From d4a014bed93b415e4b9b77ac5bce1524b73c6b87 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Sun, 1 Feb 2015 14:49:07 -0500 Subject: [PATCH 10/12] Better debug output in deployment_config_controller --- .../deployment_config_controller.go | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/pkg/deploy/controller/deployment_config_controller.go b/pkg/deploy/controller/deployment_config_controller.go index a003ab11db81..fbbab001edc7 100644 --- a/pkg/deploy/controller/deployment_config_controller.go +++ b/pkg/deploy/controller/deployment_config_controller.go @@ -1,11 +1,14 @@ package controller import ( + "fmt" + kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/golang/glog" + deployapi "github.com/openshift/origin/pkg/deploy/api" deployutil "github.com/openshift/origin/pkg/deploy/util" ) @@ -43,30 +46,30 @@ func (c *DeploymentConfigController) HandleDeploymentConfig() { config := c.NextDeploymentConfig() deploy, err := c.shouldDeploy(config) if err != nil { - // TODO: better error handling - glog.V(2).Infof("Error determining whether to redeploy deploymentConfig %v: %#v", config.Name, err) + util.HandleError(fmt.Errorf("unable to decide whether to redeploy %s: %v", labelFor(config), err)) return } - if !deploy { - glog.V(4).Infof("Won't deploy from config %s", config.Name) return } - if deployment, err := deployutil.MakeDeployment(config, c.Codec); err != nil { - glog.V(2).Infof("Error making deployment from config %s: %v", config.Name, err) - } else { - glog.V(2).Infof("Creating new deployment from config %s", config.Name) - if _, deployErr := c.DeploymentInterface.CreateDeployment(config.Namespace, deployment); deployErr != nil { - glog.V(2).Infof("Error deploying config %s: %v", config.Name, deployErr) - } + deployment, err := deployutil.MakeDeployment(config, c.Codec) + if err != nil { + util.HandleError(fmt.Errorf("unable to create deployment for %s: %v", labelFor(config), err)) + return + } + + glog.V(4).Infof("Deploying %s", labelFor(config)) + if _, deployErr := c.DeploymentInterface.CreateDeployment(config.Namespace, deployment); deployErr != nil { + util.HandleError(fmt.Errorf("unable to create deployment %s: %v", labelFor(config), err)) + return } } // shouldDeploy returns true if the DeploymentConfig should have a new Deployment created. func (c *DeploymentConfigController) shouldDeploy(config *deployapi.DeploymentConfig) (bool, error) { if config.LatestVersion == 0 { - glog.V(4).Infof("Shouldn't deploy config %s with LatestVersion=0", config.Name) + glog.V(5).Infof("Waiting for first version of %s", labelFor(config)) return false, nil } @@ -75,13 +78,15 @@ func (c *DeploymentConfigController) shouldDeploy(config *deployapi.DeploymentCo if err != nil { if errors.IsNotFound(err) { - glog.V(4).Infof("Should deploy config %s because there's no latest deployment", config.Name) return true, nil } - glog.V(4).Infof("Shouldn't deploy config %s because of an error looking up latest deployment", config.Name) return false, err } - glog.V(4).Infof("Shouldn't deploy because a deployment '%s' already exists for config %s", deployment.Name, config.Name) + glog.V(5).Infof("Found deployment for %s - %s:%s", labelFor(config), deployment.UID, deployment.ResourceVersion) return false, nil } + +func labelFor(config *deployapi.DeploymentConfig) string { + return fmt.Sprintf("%s/%s:%d", config.Namespace, config.Name, config.LatestVersion) +} From ad671275726a63a8fa1e1b3642802825c5007d7b Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Sun, 1 Feb 2015 14:50:02 -0500 Subject: [PATCH 11/12] Refactor to match upstream master changes --- hack/test-end-to-end.sh | 1 - pkg/build/controller/factory/factory.go | 4 ++-- pkg/cmd/server/kubernetes/master.go | 17 ++++++++++++----- pkg/cmd/server/start.go | 2 +- pkg/deploy/controller/factory/factory.go | 4 ++-- pkg/template/template_test.go | 2 +- pkg/util/validate.go | 4 +--- test/integration/buildclient_test.go | 13 ++++++------- test/integration/deploy_trigger_test.go | 13 ++++++------- test/integration/imageclient_test.go | 11 +++++------ 10 files changed, 36 insertions(+), 35 deletions(-) diff --git a/hack/test-end-to-end.sh b/hack/test-end-to-end.sh index 49faa46970d1..8962bb00076d 100755 --- a/hack/test-end-to-end.sh +++ b/hack/test-end-to-end.sh @@ -65,7 +65,6 @@ export PATH="${GO_OUT}:${PATH}" function cleanup() { out=$? - echo if [ $out -ne 0 ]; then echo "[FAIL] !!!!! Test Failed !!!!" diff --git a/pkg/build/controller/factory/factory.go b/pkg/build/controller/factory/factory.go index f0ca792c7fad..439ed36e11e2 100644 --- a/pkg/build/controller/factory/factory.go +++ b/pkg/build/controller/factory/factory.go @@ -144,8 +144,8 @@ func (pe *podEnumerator) Len() int { } // Get returns the item (and ID) with the particular index. -func (pe *podEnumerator) Get(index int) (string, interface{}) { - return pe.Items[index].Name, &pe.Items[index] +func (pe *podEnumerator) Get(index int) interface{} { + return &pe.Items[index] } type typeBasedFactoryStrategy struct { diff --git a/pkg/cmd/server/kubernetes/master.go b/pkg/cmd/server/kubernetes/master.go index d2b30a53bf50..2c9d363a9818 100644 --- a/pkg/cmd/server/kubernetes/master.go +++ b/pkg/cmd/server/kubernetes/master.go @@ -78,9 +78,8 @@ func (c *MasterConfig) InstallAPI(container *restful.Container) []string { ReadWritePort: c.MasterPort, ReadOnlyPort: c.MasterPort, - Client: c.KubeClient, - EtcdHelper: c.EtcdHelper, - HealthCheckMinions: true, + Client: c.KubeClient, + EtcdHelper: c.EtcdHelper, EventTTL: 2 * time.Hour, @@ -139,8 +138,16 @@ func (c *MasterConfig) RunMinionController() { }, } - minionController := minionControllerPkg.NewNodeController(nil, "", c.NodeHosts, nodeResources, c.KubeClient) - minionController.Run(10 * time.Second) + // TODO: enable this for TLS and make configurable + kubeletClient, err := kclient.NewKubeletClient(&kclient.KubeletConfig{ + Port: 10250, + EnableHttps: false, + }) + if err != nil { + glog.Fatalf("Failure to create kubelet client: %v", err) + } + minionController := minionControllerPkg.NewNodeController(nil, "", c.NodeHosts, nodeResources, c.KubeClient, kubeletClient) + minionController.Run(10*time.Second, 10) glog.Infof("Started Kubernetes Minion Controller") } diff --git a/pkg/cmd/server/start.go b/pkg/cmd/server/start.go index e662f770d635..bad9e10e0886 100644 --- a/pkg/cmd/server/start.go +++ b/pkg/cmd/server/start.go @@ -546,7 +546,7 @@ func start(cfg *config, args []string) error { VolumeDir: cfg.VolumeDir, - NetworkContainerImage: env("KUBERNETES_NETWORK_CONTAINER_IMAGE", kubelet.NetworkContainerImage), + NetworkContainerImage: env("KUBERNETES_NETWORK_CONTAINER_IMAGE", kubelet.PodInfraContainerImage), Client: existingKubeClient, } diff --git a/pkg/deploy/controller/factory/factory.go b/pkg/deploy/controller/factory/factory.go index f89c4b807fc9..552b6f3ac291 100644 --- a/pkg/deploy/controller/factory/factory.go +++ b/pkg/deploy/controller/factory/factory.go @@ -185,8 +185,8 @@ func (pe *podEnumerator) Len() int { } // Get returns the item (and ID) with the particular index. -func (pe *podEnumerator) Get(index int) (string, interface{}) { - return pe.Items[index].Name, &pe.Items[index] +func (pe *podEnumerator) Get(index int) interface{} { + return &pe.Items[index] } // DeploymentConfigChangeControllerFactory can create a DeploymentConfigChangeController which obtains DeploymentConfigs diff --git a/pkg/template/template_test.go b/pkg/template/template_test.go index 125d682d745c..664a483abe52 100644 --- a/pkg/template/template_test.go +++ b/pkg/template/template_test.go @@ -129,5 +129,5 @@ func ExampleProcessTemplateParameters() { } // Output: // - //{"kind":"Config","apiVersion":"v1beta1","metadata":{"creationTimestamp":null},"items":[{"kind":"Route","apiVersion":"v1beta1","metadata":{"creationTimestamp":null},"host":"guestbook.example.com","serviceName":"frontend-service"},{"kind":"Service","id":"frontend-service","creationTimestamp":null,"apiVersion":"v1beta1","port":5432,"selector":{"name":"guestbook"},"containerPort":0},{"kind":"Service","id":"redis-master","creationTimestamp":null,"apiVersion":"v1beta1","port":10000,"selector":{"name":"redis-master"},"containerPort":0},{"kind":"Service","id":"redis-slave","creationTimestamp":null,"apiVersion":"v1beta1","port":10001,"selector":{"name":"redis-slave"},"containerPort":0},{"kind":"Pod","id":"redis-master","creationTimestamp":null,"apiVersion":"v1beta1","labels":{"name":"redis-master"},"desiredState":{"manifest":{"version":"v1beta2","id":"","volumes":null,"containers":[{"name":"master","image":"dockerfile/redis","ports":[{"containerPort":6379}],"env":[{"name":"REDIS_PASSWORD","key":"REDIS_PASSWORD","value":"P8vxbV4C"}],"imagePullPolicy":""}],"restartPolicy":{}}},"currentState":{"manifest":{"version":"","id":"","volumes":null,"containers":null,"restartPolicy":{}}}},{"kind":"ReplicationController","id":"guestbook","creationTimestamp":null,"apiVersion":"v1beta1","desiredState":{"replicas":3,"replicaSelector":{"name":"frontend-service"},"podTemplate":{"desiredState":{"manifest":{"version":"v1beta2","id":"","volumes":null,"containers":[{"name":"php-redis","image":"brendanburns/php-redis","ports":[{"hostPort":8000,"containerPort":80}],"env":[{"name":"ADMIN_USERNAME","key":"ADMIN_USERNAME","value":"adminQ3H"},{"name":"ADMIN_PASSWORD","key":"ADMIN_PASSWORD","value":"dwNJiJwW"},{"name":"REDIS_PASSWORD","key":"REDIS_PASSWORD","value":"P8vxbV4C"}],"imagePullPolicy":""}],"restartPolicy":{}}},"labels":{"name":"frontend-service"}}},"currentState":{"replicas":0,"podTemplate":{"desiredState":{"manifest":{"version":"","id":"","volumes":null,"containers":null,"restartPolicy":{}}}}}},{"kind":"ReplicationController","id":"redis-slave","creationTimestamp":null,"apiVersion":"v1beta1","desiredState":{"replicas":2,"replicaSelector":{"name":"redis-slave"},"podTemplate":{"desiredState":{"manifest":{"version":"v1beta2","id":"","volumes":null,"containers":[{"name":"slave","image":"brendanburns/redis-slave","ports":[{"hostPort":6380,"containerPort":6379}],"env":[{"name":"REDIS_PASSWORD","key":"REDIS_PASSWORD","value":"P8vxbV4C"}],"imagePullPolicy":""}],"restartPolicy":{}}},"labels":{"name":"redis-slave"}}},"currentState":{"replicas":0,"podTemplate":{"desiredState":{"manifest":{"version":"","id":"","volumes":null,"containers":null,"restartPolicy":{}}}}}}]} + //{"kind":"Config","apiVersion":"v1beta1","metadata":{"creationTimestamp":null},"items":[{"kind":"Route","apiVersion":"v1beta1","metadata":{"creationTimestamp":null},"host":"guestbook.example.com","serviceName":"frontend-service"},{"kind":"Service","id":"frontend-service","creationTimestamp":null,"apiVersion":"v1beta1","port":5432,"selector":{"name":"guestbook"},"containerPort":0},{"kind":"Service","id":"redis-master","creationTimestamp":null,"apiVersion":"v1beta1","port":10000,"selector":{"name":"redis-master"},"containerPort":0},{"kind":"Service","id":"redis-slave","creationTimestamp":null,"apiVersion":"v1beta1","port":10001,"selector":{"name":"redis-slave"},"containerPort":0},{"kind":"Pod","id":"redis-master","creationTimestamp":null,"apiVersion":"v1beta1","labels":{"name":"redis-master"},"desiredState":{"manifest":{"version":"v1beta2","id":"","volumes":null,"containers":[{"name":"master","image":"dockerfile/redis","ports":[{"containerPort":6379}],"env":[{"name":"REDIS_PASSWORD","key":"REDIS_PASSWORD","value":"P8vxbV4C"}],"imagePullPolicy":"","capabilities":{}}],"restartPolicy":{}}},"currentState":{"manifest":{"version":"","id":"","volumes":null,"containers":null,"restartPolicy":{}}}},{"kind":"ReplicationController","id":"guestbook","creationTimestamp":null,"apiVersion":"v1beta1","desiredState":{"replicas":3,"replicaSelector":{"name":"frontend-service"},"podTemplate":{"desiredState":{"manifest":{"version":"v1beta2","id":"","volumes":null,"containers":[{"name":"php-redis","image":"brendanburns/php-redis","ports":[{"hostPort":8000,"containerPort":80}],"env":[{"name":"ADMIN_USERNAME","key":"ADMIN_USERNAME","value":"adminQ3H"},{"name":"ADMIN_PASSWORD","key":"ADMIN_PASSWORD","value":"dwNJiJwW"},{"name":"REDIS_PASSWORD","key":"REDIS_PASSWORD","value":"P8vxbV4C"}],"imagePullPolicy":"","capabilities":{}}],"restartPolicy":{}}},"labels":{"name":"frontend-service"}}},"currentState":{"replicas":0,"podTemplate":{"desiredState":{"manifest":{"version":"","id":"","volumes":null,"containers":null,"restartPolicy":{}}}}}},{"kind":"ReplicationController","id":"redis-slave","creationTimestamp":null,"apiVersion":"v1beta1","desiredState":{"replicas":2,"replicaSelector":{"name":"redis-slave"},"podTemplate":{"desiredState":{"manifest":{"version":"v1beta2","id":"","volumes":null,"containers":[{"name":"slave","image":"brendanburns/redis-slave","ports":[{"hostPort":6380,"containerPort":6379}],"env":[{"name":"REDIS_PASSWORD","key":"REDIS_PASSWORD","value":"P8vxbV4C"}],"imagePullPolicy":"","capabilities":{}}],"restartPolicy":{}}},"labels":{"name":"redis-slave"}}},"currentState":{"replicas":0,"podTemplate":{"desiredState":{"manifest":{"version":"","id":"","volumes":null,"containers":null,"restartPolicy":{}}}}}}]} } diff --git a/pkg/util/validate.go b/pkg/util/validate.go index 6b8325088803..3c700980419b 100644 --- a/pkg/util/validate.go +++ b/pkg/util/validate.go @@ -27,8 +27,6 @@ func (f *fakeServiceLister) ListServices(kapi.Context) (*kapi.ServiceList, error // ValidateObject validates the runtime.Object and returns the validation errors func ValidateObject(obj runtime.Object) (errors []error) { - ctx := kapi.NewDefaultContext() - if m, err := meta.Accessor(obj); err == nil { if len(m.Namespace()) == 0 { m.SetNamespace(kapi.NamespaceDefault) @@ -39,7 +37,7 @@ func ValidateObject(obj runtime.Object) (errors []error) { case *kapi.ReplicationController: errors = validation.ValidateReplicationController(t) case *kapi.Service: - errors = validation.ValidateService(t, &fakeServiceLister{}, ctx) + errors = validation.ValidateService(t) case *kapi.Pod: errors = validation.ValidatePod(t) case *imageapi.Image: diff --git a/test/integration/buildclient_test.go b/test/integration/buildclient_test.go index 4aae63d3ab3e..5068d1bda911 100644 --- a/test/integration/buildclient_test.go +++ b/test/integration/buildclient_test.go @@ -175,13 +175,12 @@ func NewTestBuildOpenshift(t *testing.T) *testBuildOpenshift { handlerContainer := master.NewHandlerContainer(osMux) _ = master.New(&master.Config{ - Client: kubeClient, - EtcdHelper: etcdHelper, - HealthCheckMinions: false, - KubeletClient: kubeletClient, - APIPrefix: "/api", - AdmissionControl: admit.NewAlwaysAdmit(), - RestfulContainer: handlerContainer, + Client: kubeClient, + EtcdHelper: etcdHelper, + KubeletClient: kubeletClient, + APIPrefix: "/api", + AdmissionControl: admit.NewAlwaysAdmit(), + RestfulContainer: handlerContainer, }) interfaces, _ := latest.InterfacesFor(latest.Version) diff --git a/test/integration/deploy_trigger_test.go b/test/integration/deploy_trigger_test.go index 461e2003a39c..dbf75040e868 100644 --- a/test/integration/deploy_trigger_test.go +++ b/test/integration/deploy_trigger_test.go @@ -341,13 +341,12 @@ func NewTestOpenshift(t *testing.T) *testOpenshift { handlerContainer := master.NewHandlerContainer(osMux) _ = master.New(&master.Config{ - Client: kubeClient, - EtcdHelper: etcdHelper, - HealthCheckMinions: false, - KubeletClient: kubeletClient, - APIPrefix: "/api", - AdmissionControl: admit.NewAlwaysAdmit(), - RestfulContainer: handlerContainer, + Client: kubeClient, + EtcdHelper: etcdHelper, + KubeletClient: kubeletClient, + APIPrefix: "/api", + AdmissionControl: admit.NewAlwaysAdmit(), + RestfulContainer: handlerContainer, }) interfaces, _ := latest.InterfacesFor(latest.Version) diff --git a/test/integration/imageclient_test.go b/test/integration/imageclient_test.go index 3563d8839e66..50c401f20d11 100644 --- a/test/integration/imageclient_test.go +++ b/test/integration/imageclient_test.go @@ -228,12 +228,11 @@ func NewTestImageOpenShift(t *testing.T) *testImageOpenshift { handlerContainer := master.NewHandlerContainer(osMux) _ = master.New(&master.Config{ - Client: kubeClient, - EtcdHelper: etcdHelper, - HealthCheckMinions: false, - KubeletClient: kubeletClient, - APIPrefix: "/api", - RestfulContainer: handlerContainer, + Client: kubeClient, + EtcdHelper: etcdHelper, + KubeletClient: kubeletClient, + APIPrefix: "/api", + RestfulContainer: handlerContainer, }) interfaces, _ := latest.InterfacesFor(latest.Version) From 2fbc30d2fb3778ffb62ba56ebfbd1169dd4498c0 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Sun, 1 Feb 2015 18:52:19 -0500 Subject: [PATCH 12/12] Remove empty log files and use a slightly different process kill method --- hack/test-end-to-end.sh | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/hack/test-end-to-end.sh b/hack/test-end-to-end.sh index 8962bb00076d..a661dd628e68 100755 --- a/hack/test-end-to-end.sh +++ b/hack/test-end-to-end.sh @@ -84,31 +84,27 @@ function cleanup() osc get -n test builds -o template -t '{{ range .items }}{{.metadata.name}}{{ "\n" }}{{end}}' | xargs -r -l osc build-logs -n test >"${LOG_DIR}/stibuild.log" osc get -n docker builds -o template -t '{{ range .items }}{{.metadata.name}}{{ "\n" }}{{end}}' | xargs -r -l osc build-logs -n docker >"${LOG_DIR}/dockerbuild.log" osc get -n custom builds -o template -t '{{ range .items }}{{.metadata.name}}{{ "\n" }}{{end}}' | xargs -r -l osc build-logs -n custom >"${LOG_DIR}/custombuild.log" - curl -L http://localhost:4001/v2/keys/?recursive=true > "${ARTIFACT_DIR}/etcd_dump.json" - set -e - - echo "" + echo - set +u - if [ "$SKIP_TEARDOWN" != "1" ]; then - set +e + if [[ -z "${SKIP_TEARDOWN-}" ]]; then echo "[INFO] Tearing down test" - sudo pkill -P $$ - echo "[INFO] Stopping k8s docker containers"; docker ps | awk '{ print $NF " " $1 }' | grep ^k8s_ | awk '{print $2}' | xargs -l -r docker stop + pgid="$(ps opgid= "$$")" + sudo kill -- "-${pgid}" set +u - if [ "$SKIP_IMAGE_CLEANUP" != "1" ]; then + echo "[INFO] Stopping k8s docker containers"; docker ps | awk '{ print $NF " " $1 }' | grep ^k8s_ | awk '{print $2}' | xargs -l -r docker stop + if [[ -z "${SKIP_IMAGE_CLEANUP-}" ]]; then echo "[INFO] Removing k8s docker containers"; docker ps -a | awk '{ print $NF " " $1 }' | grep ^k8s_ | awk '{print $2}' | xargs -l -r docker rm fi set -u - set -e fi - set -u - set -e + + # clean up zero byte log files # Clean up large log files so they don't end up on jenkins - find ${ARTIFACT_DIR} -size +20M -exec echo Deleting {} because it is too big. \; -exec rm -f {} \; - find ${LOG_DIR} -size +20M -exec echo Deleting {} because it is too big. \; -exec rm -f {} \; + find ${ARTIFACT_DIR} -name *.log -size +20M -exec echo Deleting {} because it is too big. \; -exec rm -f {} \; + find ${LOG_DIR} -name *.log -size +20M -exec echo Deleting {} because it is too big. \; -exec rm -f {} \; + find ${LOG_DIR} -name *.log -size 0 -exec echo Deleting {} because it is empty. \; -exec rm -f {} \; echo "[INFO] Exiting" exit $out